Comparator.comparing()函数如何工作?

时间:2016-06-23 13:58:39

标签: java-8 compare comparator comparable compareto

对于以下代码:

ForComparatorDemo object1 = new ForComparatorDemo("object-1",5);
ForComparatorDemo object2 = new ForComparatorDemo("object-2",4);
ForComparatorDemo object3 = new ForComparatorDemo("object-3",3);
ForComparatorDemo object4 = new ForComparatorDemo("object-4",4);

List<ForComparatorDemo> objectList = new ArrayList<>();
objectList.add(object1);
objectList.add(object2);
objectList.add(object3);
objectList.add(object4);
Comparator<ForComparatorDemo> comparer = Comparator.comparing(ForComparatorDemo::getAge);
objectList.sort(comparer);
objectList.forEach(object -> System.out.println(object.getName() + " " + object.getAge()));

我得到了这个输出(这是正确的):

object-3 3

object-2 4

object-4 4

object-1 5

问题是比较功能实际上是如何工作的? 在深入研究文档后,我发现了Coamparator.comparing(..)函数的代码:

public static <T, U extends Comparable<? super U>> Comparator<T> comparing(
        Function<? super T, ? extends U> keyExtractor)
{
    Objects.requireNonNull(keyExtractor);
    return (Comparator<T> & Serializable)
        (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
}

你能解释一下这个函数如何得到这两个值(c1和c2)以及return语句实际上是如何工作的?

1 个答案:

答案 0 :(得分:3)

方法comparing()不会比较事情。

它返回新的Comparator,它被描述为lamda。这是可能的,因为Comparator接口是FunctionalInterface。

所以,这段代码

(Comparator<T> & Serializable)
        (c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));

相当于:

new Comparator<T>() {
    int compare(T c1, T c2) {
        return keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));
    } 
}

所以c1c2是参数的名称。

项目按密钥进行比较,密钥由keyExtractor函数提取。

实际对象从实际使用比较器的地方传递到compare()方法。通常,这些是不同的排序方法,其中所有集合值通过via循环或迭代器迭代,并相互比较到某个外部值。例如,您可以查看Arrays.mergeSort