I have Stream<Map<String, String>>
where each map is like a separate record and contains two entries:
- Car Id ("ID", "1003")
- Kilometers ("KMI", "500")
This list might contain maps which are duplicate in a way that 2 or more maps could have the same value of car id entry. Basically this: entry1.get("ID") == entry2.get("ID"). what i want to do is to remove maps with duplicate ids but then also to merge KMI values together. this:
{"ID":"1003","KMI":"500"}, {"ID":"1003","KMI":"400"}, {"ID":"1004","KMI":"200"}
should become this:
{"ID":"1003","KMI":"900"}, {"ID":"1004","KMI":"200"}
I have tried doing it with streams API alone, but I can't wrap my head around this. I tried modifying a similar example which was having List of objects here is what I got so far:
List<Map<String, String>> result = new ArrayList<>(
queryKmAll.collect(
Collectors.toMap(a1 -> a1.get("ID")), Function.identity(), (Map<String, String> m2, Map<String, String> m1) -> {
m1.put("KMI", String.valueOf(Double.parseDouble(m1.get("KMI")) + Double.parseDouble(m2.get("KMI"))));
return m1;
})
)
);
I have picked up from where OP left. I have modified your logic a bit to return what you wanted. Have a look at it. Hope it helps
Collectors.toMap will return a map which will have ID
as key and sum of KMI
for Function.identity()
cases. So the return would be Map<Object,Map<String,String>>
. Because expected output is Stream<Map<String,String>
, I added .values().stream()
.
Stream<Map<String, String>> result = queryKmAll.collect(Collectors.toMap(a1 -> a1.get("ID"),
Function.identity(), (Map<String, String> m2, Map<String, String> m1) -> {
m1.put("KMI",
String.valueOf(Double.parseDouble(m1.get("KMI")) + Double.parseDouble(m2.get("KMI"))));
return m1;
})).values().stream();
result.forEach(System.out::println);