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?
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())
.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With