Inverse Map where getValue returns a List

cbm64 :

I would like to transform a Map<String, List<Object>> so it becomes Map<String, String>. If it were just Map<String, Object> it is easy in Java8;

stream().collect(k -> k.getValue().getMyKey(), Entry::getKey);

But this will not work because getValue returns a List Map<List<Object>, String> in my example. Assume Object contains a getter to be used for the key and that Object does not contain the key in the first map.

Any thoughts?

Ousmane D. :

Stream over the list of objects and extract the key you need then map --> flatten --> toMap

source.entrySet()
      .stream()
      .flatMap(e -> e.getValue()
                     .stream()
                     .map(x -> new SimpleEntry<>(x.getMyKey(), e.getKey())))
      .collect(toMap(SimpleEntry::getKey, SimpleEntry::getValue));

use a merge function if there is expected to be duplicate getMyKey() values:

source.entrySet()
      .stream()
      .flatMap(e -> e.getValue()
                     .stream()
                     .map(x -> new SimpleEntry<>(x.getMyKey(), e.getKey())))
      .collect(toMap(SimpleEntry::getKey, SimpleEntry::getValue, (l, r) -> l));

Note: the above uses the source map keys as the values of the resulting map as that's what you seem to be illustrating in your post, if however you want the key of the source map to remain as the key of the resulting map then change new SimpleEntry<>(x.getMyKey(), e.getKey()) to new SimpleEntry<>(e.getKey(),x.getMyKey()).

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=68135&siteId=1