I want to use a method reference based off another method reference. It's kind of hard to explain, so I'll give you an example:
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;
}
}
Given a list of Persons, I want to use method references to get a list of their sibling's ages. I know this can be done like this:
roster.stream().map(p -> p.getSibling().getAge()).collect(Collectors.toList());
But I'm wondering if it's possible to do it more like this:
roster.stream().map(Person::getSibling::getAge).collect(Collectors.toList());
It's not terribly useful in this example, I just want to know what's possible.
-
6Chain of Map method referencesrgettman– rgettman2016年03月24日 17:06:57 +00:00Commented Mar 24, 2016 at 17:06
3 Answers 3
You need to use two map operations in that case:
roster.stream().map(Person::getSibling).map(Person::getAge).collect(Collectors.toList());
The first one maps the Person to its sibling and the second one maps the Person to its age.
Comments
You can use Functions.chain() from Eclipse Collections to chain method references:
MutableList<Person> roster = Lists.mutable.empty();
MutableList<Integer> ages =
roster.collect(Functions.chain(Person::getSibling, Person::getAge));
If you can’t change roster from List
List<Person> roster = Lists.mutable.empty();
List<Integer> ages =
ListAdapter.adapt(roster).collect(Functions.chain(Person::getSibling, Person::getAge));
Since age is an int, you can avoid boxing by using an IntList:
MutableList<Person> roster = Lists.mutable.empty();
IntList ages = roster.collectInt(Functions.chainInt(Person::getSibling, Person::getAge));
Note: I am a contributor to Eclipse Collections.
Comments
Use Function.andThen, and possibly wrap your first method reference in a call, or cast.
public static <V, R> Function<V,R> ofFunction(Function<V,R> function) {
return function;
}
roster.collect(ofFunction(Person::getSibling).andThen(Person::getAge));