I am looking to merge the lists in a list if the 1st index match in Java8. I have a list of lists
[[ABC, 1.0, 4.0, 4.0], [ABC, 2.0, 4.0, 4.0], [ABC, 1.0, 72.0, 72.0], [XYZ, 1.0, 36.0, 36.0], [XYZ, 2.0, 16.0, 16.0]]
And I want the result as below in an effective way like using stream in java. Result should be
[[ABC, 4.0, 116.0, 116.0], [XYZ, 3.0, 52.0, 52.0]]
Could anyone help please?
CodePudding user response:
In this case Collectors.toMap
should be used with the key selected as the first index, and a merge function to sum the rest elements.
Example:
List<List<Object>> input = ...;
List<List> merged = new ArrayList<>(input.stream()
.collect(Collectors.toMap(
list -> list.get(0),
list -> list,
(l1, l2) -> Stream.concat(
Stream.of(l1.get(0))),
IntStream.range(1, l1.size())
.mapToObj(i -> (Double)l1.get(i) (Double)l2.get(i))
)
.collect(Collectors.toList()),
LinkedHashMap::new // keep insertion order
))
.values() // Collection<List<Object>>
);
However, the input lists seem to be a mix of String and double data and they should be better converted into a class/record.
CodePudding user response:
- For each list in the list of lists
- If first value is not in hashmap add to hashmap using first value as key
- If key is already in hashmap merge with list already in hashmap
- Create new list of lists based on hashmap entry set
Extra credit: use LinkedHashMap to preserve order of appearance or TreeMap if you want it in alphabetical order