Assuming I'm writing a method that takes in Map<String, List<Integer>>
as shown below, and a String name
to filter. My return type is Stream<Integer>
how do I convert from a Stream<List<Integer>>
to Stream<Integer>
?
Map<String, List<Integer>> person = Map.of("John", List.of(54, 18),
"Alex", List.of(28),
"Tom", List.of(78, 42));
My current implementation returns a Stream<List<Integer>>
. Realistically, I would iterate through the list to retrieve all Integers in the list.
Code implementation:
return table.entrySet().stream()
.filter(map -> map.getKey().equals(name))
.map(map -> map.getValue());
CodePudding user response:
As @Thomas has pointed out in the comments, iterating over the whole Map would be wasteful. And solution he proposed probably is the cleanest one:
map.getOrDefault(name, Collections.emptyList()).stream()
Alternatively, you can make use of flatMap()
without performing redundant iteration through the whole map like that:
public static <K, V> Stream<V> getStreamByKey(Map<K, Collection<V>> map,
K key) {
return Stream.ofNullable(map.get(key))
.flatMap(Collection::stream);
}
The same result can be achieved with Java 16 mapMulti()
:
public static <K, V> Stream<V> getStreamByKey(Map<K, Collection<V>> map,
K key) {
return Stream.ofNullable(map.get(key))
.mapMulti(Iterable::forEach);
}
CodePudding user response:
As others pointed out in comments, use flatMap
instead of map
in the last step to reduce the double nesting:
return table.entrySet().stream()
.filter(map -> map.getKey().equals(name))
.flatMap(entry -> entry.getValue().stream());