Как создается компаратор из ссылки на метод? - PullRequest
0 голосов
/ 20 ноября 2018

Я изучаю лямбда-выражения.Я не понимаю, как компаратор возвращается из ссылки на метод.

Я хочу отсортировать список людей по возрасту.

Для этого у меня есть метод, чтобы найти разницу в возрасте:

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

Метод sorted нуждается в качестве параметра a Comparator

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

Мое лямбда-выражение:

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

Как 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]

1 Ответ

0 голосов
/ 20 ноября 2018

Полагаю, ваша главная путаница заключается в следующем:

Comparator<T> представляет метод, который принимает два параметра типа T и возвращает int.Мой метод ageDifference принимает только один параметр Person.Как это может стать Comparator<Person>?

Обратите внимание, что ageDifference является методом экземпляра.Чтобы вызвать его, вам нужны не только параметры, но и экземпляр Person.В этом случае вам нужно 2 Person s для вызова метода - один, для которого вы вызываете ageDifference, а другой - как параметр:

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

Разве это не точно так же, как метод static, который принимает два параметра?

Следовательно, Java достаточно умен, чтобы знать, что вам нужно два человека для вызова Person::ageDifference, поэтому ссылка на метод рассматривается как имеющая двапараметры.

В общем случае метод экземпляра класса T, принимающий параметры P1, P2 ... Pn и возвращающий тип R, может рассматриваться как статический метод, принимающий параметрыT, P1, P2 ... Pn и возвращение R.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...