Given the following as an example of data classes:
class Country {
List<Region> regions = new ArrayList<>();
List<Region> getRegions() {
return regions;
}
}
class Region {
String getName() {
return "some name";
}
}
Presuming I would have a List of Countries
List<Country> countries = new ArrayList<>();
And I wanted to Stream those to their Regions and their corresponding names I would like to do the following:
countries.stream().flatMap(Country::getRegions).map(Region::getName)...
However that code does not compile since the return value of "getRegions" is a Collection (List) as opposed to a Stream, which the flatMap Method accepts. But since I know that any Collection can be streamed via its Collection.stream() Method that shouldn't be a problem. Still I am forced to write it as follows:
countries.stream().flatMap(c -> c.getRegions().stream()).map(Region::getName)...
Which is (given a richer context) far less readable than the former.
Questions is, is there any reason, that I am missing out on, for this to be that bulky? I have plenty of examples in our framework at which I am forced to take that route, always leaving me with a sour taste. (Guess I just have to add Kotlin to our projects and extend the Stream class with a flatMap Method that takes a Collection :p or do I?)
flatMap
should accept a collection, but I'm not sure SO is going to be able to provide a definitive explanation, other than "the people that wrote it didn't write it that way". – IllomenedStream<Country>
from the method instead. Or add a methodregions
that does that. – Merete.map(Country::getRegions).flatMap(List::stream)
, but I don’t get why method references are considered so superior to a simple lambda expression… – Slangy