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 Person
s, 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.
In those cases, it's often clearer to refer to the existing method by name. Method references enable you to do this; they are compact, easy-to-read lambda expressions for methods that already have a name.
The method references can only be used to replace a single method of the lambda expression. A code is more clear and short if one uses a lambda expression rather than using an anonymous class and one can use method reference rather than using a single function lambda expression to achieve the same.
The double colon (::) operator, also known as method reference operator in Java, is used to call a method by referring to it with the help of its class directly. They behave exactly as the lambda expressions.
Method Reference in java 8 makes the code simple and more readable than lambda expression. Method reference refers to the method via the use of an :: operator. A method reference in Java 8 can execute only a single method call like a lambda expression but a shorter code.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With