5

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?

Naman
  • 27,789
  • 26
  • 218
  • 353
cbm64
  • 1,059
  • 2
  • 12
  • 24
  • can you explain the bit... *and that Object does not contain the key in the first map.* ? – Naman Nov 27 '18 at 11:53

2 Answers2

4

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()).

Ousmane D.
  • 54,915
  • 8
  • 91
  • 126
1

If preference could be to choose any amongst the multiple values mapped as a key, you can simply use:

Map<String, List<YourObject>> existing = new HashMap<>();
Map<String, String> output = new HashMap<>();
existing.forEach((k, v) -> v.forEach(v1 -> output.put(v1.getMyKey(), k)));

Essentially this would put the 'first' such myKey along with its corresponding value which was the key of the existing map.

Naman
  • 27,789
  • 26
  • 218
  • 353