Creating map from list, where key is in part of inner and outer object

Viewed 103

Is it possible (in simple way) to change it into java8 Stream? (Please do not comment/answer if you want to tell me that two for are better and not all loops should be changed to streams, it's not a point)

final Map<String, String> map = new HashMap<>();

for(final Person person: list) {
    for(final Internal internal: person.getInternals()) {
        final String key = person.getName() + internal.getKey();
        map.put(key, internal.getValue());
    }
}

The main problem is that I can't use flatMap because I will lose previous information. Each created key is unique.

2 Answers

Well you could pass those along via a Pair (I have not compiled this though, but the idea should be there)

 list.stream()
    .flatMap(person -> person.getInternals()
                       .stream()
                       .map(internal -> 
                           Pair.of(person.getName() + internal.getKey(), internal.getValue()))
    .collect(Collectors.toMap(Pair::getLeft, Pair::getRight));

You can use collect directly and if you are sure that each created key is unique, as you mentioned, the accumulator and combiner are simple to write:

Map<String, String> map =
    list.stream().collect(HashMap::new,
                          (m, p) -> p.getInternals().forEach(i -> m.put(p.getName() + i.getKey(), i.getValue())),
                          Map::putAll);
Related