Reputation: 3059
What I read about flatMap:
To understand what flattening a stream consists in, consider a structure like [ [1,2,3],[4,5,6],[7,8,9] ] which has "two levels". Flattening this means transforming it in a "one level" structure : [ 1,2,3,4,5,6,7,8,9 ]
import java.util.List;
import java.util.stream.Stream;
public class FlatMapDemo {
List<Country> countries;
void demoFlatMap(){
Stream<Stream<City>> streamStreamCity = countries
.stream()
.map(country -> country.cities.stream());
streamStreamCity.flatMap(cityStream -> /*it's not City, it's Stream<City> !!!*/);
}
}
class Country{
List<City> cities;
}
class City {
int population;
}
So I just wanna count all population from all countries but in cities which has > 1000 inhabitants. So I created Stream<Stream<City>>
and hope flatMap flat for me Stream<Stream
and give me City class to take something like: .flatMap(city -> city.population)
to filter after: .filter(population > 1000)
but it seems I was wrong. Please explain why flatMap doesn't do this? Isn't it the purpose of flattening?
Upvotes: 0
Views: 200
Reputation: 20618
The goal of flatMap()
is not to apply a transformation on the A
items of a Stream<Stream<A>>
. If you end up with such a type it most likely indicates you misused a map()
operation somewhere.
The goal of flatMap()
is instead to transform a Stream<A>
into a Stream<B>
when you have a function f
that can produce a Stream<B>
from individual A
elements (simplifying a bit, it is a Function<A, Stream<B>>
). I.e. it “flattens” the stream by avoiding to end up with nested streams.
You would use it like
getStreamOfA().flatMap(f) // returns Stream<B>
So in your example:
Stream<City> cityStream = countries
.stream()
.flatMap(country -> country.cities.stream());
Upvotes: 1