Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java8: method reference from another method reference

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.

like image 766
ewok Avatar asked Mar 24 '16 16:03

ewok


People also ask

Does method references point to methods using their names?

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.

How does method reference work in Java 8?

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.

What is :: called in Java 8?

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.

What is the benefit of using method reference in Java 8?

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.


2 Answers

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.

like image 80
Tunaki Avatar answered Oct 02 '22 02:10

Tunaki


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.

like image 2
Nikhil Nanivadekar Avatar answered Oct 02 '22 03:10

Nikhil Nanivadekar