Java8: ссылка на метод из другого метода ссылка
Я хочу использовать ссылку на метод, основанную на другом методе ссылки. Это трудно объяснить, поэтому я приведу вам пример:
Person.java
public class Person{
Person sibling;
int age;
public Person(int age){
this.age = age;
}
public void setSibling(Person p){
this.sibling = p;
}
public Person getSibling(){
return sibling;
}
public int getAge(){
return age;
}
}
Учитывая список Person
s, я хочу использовать ссылки на методы, чтобы получить список их возраста. Я знаю, что это можно сделать следующим образом:
roster.stream().map(p -> p.getSibling().getAge()).collect(Collectors.toList());
Но мне интересно, возможно ли это сделать больше:
roster.stream().map(Person::getSibling::getAge).collect(Collectors.toList());
Это не очень полезно в этом примере, я просто хочу знать, что возможно.
Ответы
Ответ 1
В этом случае вам нужно использовать две операции map
:
roster.stream().map(Person::getSibling).map(Person::getAge).collect(Collectors.toList());
Первый отображает Person
его родному брату, а второй отображает Person
в его возраст.
Ответ 2
Вы можете использовать Functions.chain()
из Eclipse Collections для ссылок на цепочку:
MutableList<Person> roster = Lists.mutable.empty();
MutableList<Integer> ages =
roster.collect(Functions.chain(Person::getSibling, Person::getAge));
Если вы не можете изменить список из List
List<Person> roster = Lists.mutable.empty();
List<Integer> ages =
ListAdapter.adapt(roster).collect(Functions.chain(Person::getSibling, Person::getAge));
Поскольку возраст - int
, вы можете избежать бокса, используя IntList:
MutableList<Person> roster = Lists.mutable.empty();
IntList ages = roster.collectInt(Functions.chainInt(Person::getSibling, Person::getAge));
Примечание. Я участвую в коллекциях Eclipse.
Ответ 3
Используйте Function.andThen и, возможно, оберните свою первую ссылку на метод в вызове или произведите.
public static <V, R> Function<V,R> ofFunction(Function<V,R> function) {
return function;
}
roster.collect(ofFunction(Person::getSibling).andThen(Person::getAge));