How do I merge a map list into a map?
Can you help me solve Java streams?
As you can see from the title, I need to merge list < map < string, map < string, genuineness > > to map < string, genuineness > >
The list is represented as list < map < string, genuineness > > > and looks like:
[ { "USER_1":{ "APP_1":{ "total":1,"totalGenuine":1,"totalDevelopment":1 } },"USER_2":{ "APP_1":{ "total":1,"totalDevelopment":1 },"APP_2":{ "total":2,"totalGenuine":2,"totalDevelopment":2 } } },{ "USER_1":{ "APP_1":{ "total":1,"totalDevelopment":2 } } } ]
So, as you can see, duplicate keys can be everywhere My goal is to combine them into map < < string, genuineness > > by merging authenticity Merging authenticity simply means returning a new object with the sum of total, totalgenius, and totaldevelopment
This is my implementation failure:
final Map<String,Map<String,Genuineness>> map = taskHandles.stream().map(this::mapTaskHandle) .flatMap(m -> m.entrySet().stream()).collect( Collectors.toMap(Map.Entry::getKey,e -> e.getValue().entrySet().stream() .collect( Collectors.toMap(Map.Entry::getKey,g -> new Genuineness(g.getValue().getTotal(),g.getValue().getTotalGenuine(),g.getValue().getTotalDevelopment()),(g1,g2) -> new Genuineness(g1.getTotal() + g2.getTotal(),g1.getTotalGenuine() + g2.getTotalGenuine(),g1.getTotalDevelopment() + g2.getTotalGenuine() ) ) ) ) );
It failed with the message:
java.lang.IllegalStateException: Duplicate key {TEST_33_33_APP_1=live.attach.billing.domain.model.billing.Genuineness@951b6fe}
So, it seems that in my implementation, I have pointed out how to combine internal maps, but I don't know what to do without merging the values of external maps
I appreciate your help very much Thank you first!
Update: expected production:
{ "USER_1":{ "APP_1":{ "total":2,"totalDevelopment":2 } },"USER_2":{ "APP_1":{ "total":2,"totalDevelopment":2 },"APP_2":{ "total":4,"totalGenuine":4,"totalDevelopment":4 } } }
Solution
To be honest, this is a terrible data structure, and it is difficult for the maintainer of this code to find the problem
You should take a step back and consider refactoring the code. You can solve the missing part by using the following merge function in the outermost tomap:
(l,r) -> { r.forEach((k,v) -> l.merge(k,v,(bi,bii) -> new Genuineness(bi.getTotal() + bii.getTotal(),bi.getTotalGenuine() + bii.getTotalGenuine(),bi.getTotalDevelopment() + bii.getTotalGenuine()))); return l; }
Full code:
taskHandles.stream().map(this::mapTaskHandle) .flatMap(m -> m.entrySet().stream()).collect( Collectors.toMap(Map.Entry::getKey,g1.getTotalDevelopment() + g2.getTotalGenuine() ) ) ),(l,r) -> { r.forEach((k,bi.getTotalDevelopment() + bii.getTotalGenuine()))); return l; } ) );
Ideone