Home > Enterprise >  combine hashmaps of Arrays into array using stream API
combine hashmaps of Arrays into array using stream API

Time:10-10

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);
  • Related