【JAVA Lambda】初学者对Comparator.comparing(Person::getLastName).thenComparing(Person::getFirstName)套娃的理解

最近在看《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♪(・ω・)ノ

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值