Java中Comparator.comparing()方法的键提取比较逻辑是如何实现的?
Comparator.comparing() 比较执行逻辑解答
你的猜想完全正确,Comparator.comparing() 返回的比较器在调用compare方法时,本质就是执行你提到的类似 t1.getLastName().compareTo(t2.getLastName()) 的逻辑,只是做了通用的泛型封装。
核心实现逻辑
JDK 中comparing方法返回的Comparator实例的compare方法核心源码逻辑可以简化为如下形式:
@Override public int compare(T t1, T t2) { // 用传入的键提取函数分别从两个待比较对象中提取排序键 U key1 = keyExtractor.apply(t1); U key2 = keyExtractor.apply(t2); // 调用排序键自身的compareTo方法完成比较 return key1.compareTo(key2); }
其中keyExtractor就是你调用comparing方法时传入的函数,比如例子中的Person::getLastName。
对应示例的执行流程
你例子中的byLastName比较器执行比较时,流程如下:
- 当排序逻辑调用
byLastName.compare(p1, p2)时,首先通过方法引用提取两个Person对象的姓氏:p1.getLastName()、p2.getLastName() - 调用String类实现的
compareTo方法,对两个姓氏字符串做字典序比较,返回的结果直接作为两个Person对象的比较结果,和你手动写的比较逻辑完全一致。
补充说明
- 原生的
Comparator.comparing没有处理键为null的场景,如果提取出的排序键可能为null,需要搭配Comparator.nullsFirst()或Comparator.nullsLast()对比较器做包装,避免抛出空指针异常。 - 泛型约束
U extends Comparable<? super U>保证了提取出的排序键一定实现了Comparable接口,一定可以调用compareTo方法完成比较。
内容的提问来源于stack exchange,提问作者Display name
相关产品推荐
相关产品推荐

