I have a map with such structure: Map<R, Map<S, Map<D, K>>>
and I need to convert it to Map<R, Map<D, Map<S, K>>>
any idea how to implement it with streams?
In my case it looks like: Map<Long, Map<String, Map<Long, Double>>>
And the data:
{1->{"m"->{2->3.0},{3->1.0},{4->2.0}}}
{1->{"n"->{2->1.0},{3->2.2},{5->3.2}}}
Thanks.
First off, it appears that the outer map level is not involved in the transformation, so let's forget about it for the time being. You have Map<S,Map<D,K>>
and you want to turn it into Map<D,Map<S,K>>
. You could try the following:
Map<S,Map<D,K>> src = ...;
Map<D,Map<S,K>> dest = src.entrySet().stream() // Stream<Map.Entry<S,Map<D,K>>>
.flatMap(eO -> {
final S curS = eO.getKey();
return eO.getValue().entrySet().stream() // Stream<Map.Entry<D,K>>
.map(eI -> new Object[] { curS, eI.getKey(), eI.getValue() });
// Stream<Object[]{S,D,K}> for this S
}) // Stream<Object[]{S,D,K}> for all S
.collect(Collectors.groupingBy(
arr -> (D)arr[1], // What to group by in the outer level
Collectors.toMap( // What to do with the inner level values for each D
arr -> (S)arr[0], // Keys for the inner map
arr -> (K)arr[2] // Values for the inner map
)));
Of course, the code might seem a bit awkward due to the use of casts, but it avoids the need for a type-safe 3-tuple class. Take a deep look at the code because I'm away from any Java compiler, but I think it ought to do what you want it to do.
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