【JAVA Lambda】初学者对Comparator.comparing(Person::getLastName).thenComparing(Person::getFirstName)套娃的理解
2020-04-07 17:23
113 查看
最近在看《JAVA 核心技术 卷一》 对Comparator.comparing().thenComparing()这个套娃有点不解然后研究了一下。
Arrays.sort(person, Comparator.comparing(Person::getLastName).thenComparing(Person::getFirstName));
一、静态方法comparing(Function<? super T, ? extends U> keyExtractor)
//comparing()方法 static <T, U extends Comparable<? super U>> Comparator<T> comparing(Function<? super T, ? extends U> keyExtractor) { Objects.requireNonNull(keyExtractor); return (Comparator)((Serializable)((c1, c2) -> { return ((Comparable)keyExtractor.apply(c1)).compareTo(keyExtractor.apply(c2)); })); }
----1. 先看传入的参数
因为Function是一个被@FunctionalInterface修饰的接口(表示其中只有一个必须实现的方法)即可以用lambda表达式
Person::getLastName()是【方法引用】相当于lambda:(Person P)->{P.getLastName()} //根据comparing的参数列表可知传入的Person::getLastName相当于下列代码 Function<Person,String> keyExtractor=(Person P)->P.getLastName();
----2.Objects.requireNonNull(keyExtractor)
//貌似是判断非空的,暂时不管他(其实是我暂时不知道2333) Objects.requireNonNull(keyExtractor)
----3.comparing方法中最关键的部分
return (Comparator)((Serializable)((c1, c2) -> { return ((Comparable)keyExtractor.apply(c1)).compareTo(keyExtractor.apply(c2)); }));
------------1)先看最里层,是一个lambda表达式
(c1, c2) -> {return ((Comparable)keyExtractor.apply(c1)).compareTo(keyExtractor.apply(c2));}
------------2)当中用到了传入的Function keyExtractor,我们将它用Person::getLastName替换便于理解
(c1, c2) -> {return ((Comparable)Person.getLastName(c1)).compareTo(Person.getLastName(c2));}
------------3)然后是一个(Comparable)的类型转换,comparing()方法中最关键的部分结束
因为要使用Comparable接口里的compareTo()比较方法,所以要进行类型转换
----4.最后comparing方法将lambda表达式转换成Comparato对象返回(Serializable好像是序列化的意思,暂时没有研究2333)
二、默认方法 default <U extends Comparable<? super U>> Comparator thenComparing(Function<? super T, ? extends U> keyExtractor)
default <U extends Comparable<? super U>> Comparator<T> thenComparing(Function<? super T, ? extends U> keyExtractor) { return this.thenComparing(comparing(keyExtractor)); } 分析过comparing()之后thenComparing()就非常简单了 过程:调用comparing()返回一个Comparator对象,然后将Comparator对象传入this.thenComparing()得到一个符合<U extends Comparable<? super U>>的Comparable类对象
三、被上一方法套娃调用的this.thenComparing()
default Comparator<T> thenComparing(Comparator<? super T> other) { Objects.requireNonNull(other); return (Comparator)((Serializable)((c1, c2) -> { //调用第一次comparing()方法所生成的Comparator对象的compare()方法 //(comparing(Person::getLastName)生成的) int res = this.compare(c1, c2); //如果res为0,两String相等,就调用第二次comparing()方法所生成的Comparator对象的compare()方法 //(thenComparing(Person::getFirstName)中comparing(keyExtractor)生成的) return res != 0 ? res : other.compare(c1, c2); })); } 这个方法的作用就是将被comparing()方法转换完的Comparator对象整合成一个lambda表达式然后转换成Comparator对象返回。
四、总结
comparing():创建第一个比较分支 thenComparing():创建其它比较分支并调用this.thenComparing() this.thenComparing():整合比较分支 有点单支二叉树的感觉(不知道是不是错觉)每一个节点就是一个判断条件(例:Person::getLastName)相等就继续往下,不相等就结束
发现不懂的地方还很多,比如泛型那一堆尖括号类似<? super T, ? extends U>这种还有Serializable、Objects.requireNonNull之类的。
如果有错误请帮忙指出。Thanks♪(・ω・)ノ
相关文章推荐
- 初学者在使用java中java.lang.Class.getResource(String name)为什么会返回null
- java中set和get方法的理解,写给初学者
- Java编程之TreeSet排序两种解决方法(1)元素自身具备比较功能,元素需要实现Comparable接口覆盖compare(2)创建根据自定义Person类的name进行排序的Comparator
- Java初学者都必须理解的六大问题
- 深入理解 lambda表达式 与 Optional Null 源码解析(Java11 三)
- gethostname()函数出错:WSAGetLastError 10093 解决方法
- java中get和set方法的理解与使用
- 深入理解Java 8 Lambda(语言篇)
- How to Get First and Last Day of a Month in SQL Server
- Java 8 Lambda : Comparator 示例
- Flex中如何利用tabStyleName, firstTabStyleName, lastTabStyleName和selectedTabTextStyleName样式定制自己的TabNavigator的例子
- Java8:Lambda表达式增强版Comparator和排序
- 【原创】Java网络编程从入门到精通(6):使用getCanonicalHostName方法获得主机名...
- Java多线程中this.getName()和Thread.currentThread.getName()的区别?
- 关于java.net.InetAddress类的getHostName方法
- lambda -- Java 8 find first element by predicate
- java线程操作方法setName,getName,isAlive
- java初学者应该理解的几个问题?
- java中set和get方法的理解
- java 中的set方法和get方法的理解