Let's say I have a map to a map of Integers and I want filter for a key to the second map and combine the arrays for the giving key.
so basically I want to go from
Map<String, Map<String, List<Integer>>>
to
List<Integer>
For example
KeyA -> keya -> [1,2,3]
KeyB -> keya -> [4,5,6]
KeyC -> keyb -> [7,8]
The result should be if the filter value is keya [1,2,3,4,5,6], I don't really care about the first set of keys.
I don't have any issues completing this operation in a standard way of iterating.
I would like to use Streams though.
CodePudding user response:
There is some mistake in your description, you can't have two same keys named "keya"
in the Map.
But, common solution by Stream API will looks like that:
List<Integer> collect = source.values().stream()
.flatMap(s -> s.entrySet().stream())
.filter(s1 -> s1.getKey().equals(1) || s1.getKey().equals(2)) //needed key here
.map(Map.Entry::getValue)
.flatMap(Collection::stream)
.collect(Collectors.toList());
for example:
Map<String, Map<Integer, List<Integer>>> source = Map.of("keyA", Map.of(1, Arrays.asList(1,2,3,5)), "keyB", Map.of(2, Arrays.asList(5,6,7,8)));
Output:
[5, 6, 7, 8, 1, 2, 3, 5]
CodePudding user response:
You can do it like this:
List<Integer> list = m
.values()
.stream()
.flatMap(innerMap ->
innerMap
.entrySet()
.stream()
.filter(entry -> entry.getKey().equals(1))
.flatMap(entry -> entry.getValue().stream()))
.collect(Collectors.toList());
CodePudding user response:
You can stream
the map
values and then filter
the ones that contain the key
and then flatMap
the nested map
values:
Map<String, Map<Integer, List<Integer>>> map = ...
private List<Integer> toList(Integer key) {
return map.values().stream()
.filter(nestedMap -> nestedMap.containsKey(key))
.map(Map::values)
.flatMap(Collection::stream)
.flatMap(List::stream)
.collect(Collectors.toList());
}
Then you can do:
List<Integer> list = toList(keya);