cbaby cbaby - 3 months ago 9
Java Question

Mapping Java 8 Stream to elements' method reference

Let's say I have an interface like this:

public interface Service {
List<Result> getResults();
// some other methods
}


I have a
List
of implementations of that interface in
List<Service> services
.

How do I transform that
List
into a
List
of method references to the
getResults
method (or even better: a
List
of
Supplier<List<Result>>
) dynamically?

I was looking for something akin to

List<Supplier<List<Result>>> = services.stream()
.map(s -> s::getResults)
.collect(Collectors.toList());

Answer

You can't include a method reference inside a lambda expression. You can, however, include a lambda expression in a lambda expression.

It seems the compiler needs some help with type inference.

List<Supplier<List<Result>>> list = 
    services.stream()
            .map(s -> (Supplier<List<Result>>)(() -> s.getResults()))
            .collect(Collectors.toList());

Here's a working example which replaces your Service interface with StringBuilder and your Result with String. I'm using Arrays.asList(s.toString().split(" ")) to produce a List<String> from each StringBuilder.

List<StringBuilder> services = new ArrayList<>();
services.add (new StringBuilder());
services.add (new StringBuilder());
services.get (0).append ("one two three");
services.get (1).append ("four five six");
List<Supplier<List<String>>> list = 
services.stream()
        .map(s -> (Supplier<List<String>>) (() -> Arrays.asList(s.toString().split(" "))))
        .collect(Collectors.toList());
System.out.println (list.get (0).get ());
System.out.println (list.get (1).get ());

Output :

[one, two, three]
[four, five, six]
Comments