问题
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?)
回答1:
A technical reason, which is not ideal but could be why this wasn't done. You can't overload on a generic type in Java.
They need to support
Stream.flatMap(Function<Object, Stream<X>> function)
which means they can't overload it with
Stream.flatMap(Function<Object, Collection<X>> function)
as these two methods have the same signature after erasure.
They could add a method
Stream.flatMapCollection(Function<Object, Collection<X>> function)
or
Stream.flatMapIterable(Function<Object, Iterable<X>> function)
Stream.flatMapI(Function<Object, Iterable<X>> function)
but it wouldn't be pretty.
来源:https://stackoverflow.com/questions/42142438/why-cant-stream-flatmap-accept-a-collection