18

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.

1

3 Answers 3

16

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.

Sign up to request clarification or add additional context in comments.

Comments

2

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

2

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));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.