首页 > 解决方案 > 如何从方法引用创建比较器?

问题描述

我正在学习 lambda 表达式。我不明白如何从方法引用返回比较器。

我想按年龄对人员列表进行排序。

为此,我有一种方法可以找到年龄差异:

public int ageDifference(final Person other) {
    return age - other.age;
}

sorted方法需要作为参数aComparator

Stream<T> sorted(Comparator<? super T> comparator);

我的 lambda 表达式是:

people.stream()
.sorted(Person::ageDifference)
.collect(toList());

a 是如何Person::ageDifference转化的Comparator<Person>

我的完整示例:

public class Person {

private final String name;
private final int age;

public Person(final String theName, final int theAge) {
    name = theName;
    age = theAge;
}

public String getName() {
    return name;
}

public int getAge() {
    return age;
}

public int ageDifference(final Person other) {
    return age - other.age;
}

public String toString() {
    return String.format("%s - %d", name, age);
}

public static void main (String args[] ){
    final List<Person> people = Arrays.asList(
            new Person("John", 10),
            new Person("Greg", 30),
            new Person("Sara", 20),
            new Person("Jane", 15));

    List<Person> ascendingAge =
            people.stream()
                    .sorted(Person::ageDifference)
                    .collect(toList());

    System.out.println(ascendingAge);
}
}

输出:[John - 10, Jane - 15, Sara - 20, Greg - 30]

标签: javalambda

解决方案


我想你的主要困惑是:

Comparator<T>表示一个方法,它接受两个类型的参数T并返回一个int. 我的ageDifference方法只接受一个Person参数。怎么会变成一个Comparator<Person>

请注意,这ageDifference是一个实例方法。要调用它,不仅需要参数,还需要Person. 在这种情况下,您需要 2Person秒来调用该方法 - 一个是您调用ageDifference的,另一个是您作为参数传递的:

me.ageDifference(someoneElse)
^                      ^
|                      |
        Two people!

这不就像一个static接受两个参数的方法吗?

因此,Java 很聪明,知道需要两个人来调用Person::ageDifference,所以方法引用被视为有两个参数。

一般来说,T接受参数P1P2...Pn和返回类型的类的实例方法R可以被视为接受参数TP1...和返回的静态方法P2PnR


推荐阅读