Reputation: 808
I would like to compose method references in a stream's collect(Collectors.toMap(..)) call. In the following example, I have code that accomplishes my task without a method reference:
class A {
private String property1;
private B property2;
public String getProperty1() { return property1; }
public B getProperty2() { return property2; }
}
class B {
private String property3;
public String getProperty3() { return property3; }
}
public class Main {
public static void Main() {
List<A> listOfA = /* get list */;
Map<String, String> = listOfA.stream()
.collect(toMap(x -> x.getProperty1(), x -> x.getProperty2().getProperty3()));
}
}
It is trivial to change x -> x.getProperty1()
to A::getProperty1()
. However it is not as trivial with x -> x.getProperty2().getProperty3()
. I would like one of the following to work:
.collect(toMap(A::getProperty1, ((Function)A::getProperty2).andThen((Function)B::getProperty3)))
or
.collect(toMap(A::getProperty1, ((Function)B::getProperty3).compose((Function)A::getProperty2)))
However, they both give me the error Non-static method cannot be referenced from static context
.
Upvotes: 4
Views: 1742
Reputation: 10948
A::getProperty2
is a Function<A, B>
(that is a Function that takes an instance of A and returns an instance of B).
You can cast and compose it as:
((Function<A, B>)A::getProperty2).andThen(B::getProperty3)
Or you can create a Function producer like:
public static <A, B, R> Function<A, R> compose(
Function<A, B> f1, Function<B, R> f2) {
return f1.andThen(f2);
}
And use it to compose as:
compose(A::getProperty2, B::getProperty3)
Upvotes: 4