Java 8 stream amount entries for duplicate keys

I use Java 8 threads to group a list of records using a specific key, and then sort the groups by date. What I would like to do in addition is to β€œcollapse” any two records within the group that have the same date and summarize them. I have a class like this (trimmed for example)

class Thing { private String key; private Date activityDate; private float value; ... } 

Then I group them like this:

 Map<String, List<Thing>> thingsByKey = thingList.stream().collect( Collectors.groupingBy( Thing::getKey, TreeMap::new, Collectors.mapping(Function.identity(), toSortedList()) )); private static Collector<Thing,?,List<Thing>> toSortedList() { return Collectors.collectingAndThen(toList(), l -> l.stream().sorted(Comparator.comparing(Thing::getActivityDate)).collect(toList())); } 

What would I like to do if any two Thing entries have the same date, sum the values ​​for them and collapse them so that

thing1 Date = 1/1/2017 Value = 10

Thing2 Date = 1/1/2017 Value = 20

Turns at 30 on 1/1/2017.

What is the best way to accomplish something like this?

+5
source share
2 answers

I changed your Thing class a bit to use LocalData and added a very simple toString :

 @Override public String toString() { return " value = " + value; } 

If I understand correctly what you need it for:

 Map<String, TreeMap<LocalDate, Thing>> result = Arrays .asList(new Thing("a", LocalDate.now().minusDays(1), 12f), new Thing("a", LocalDate.now(), 12f), new Thing("a", LocalDate.now(), 13f)) .stream() .collect(Collectors.groupingBy(Thing::getKey, Collectors.toMap(Thing::getActivityDate, Function.identity(), (Thing left, Thing right) -> new Thing(left.getKey(), left.getActivityDate(), left.getValue() + right.getValue()), TreeMap::new))); System.out.println(result); // {a={2017-06-24= value = 12.0, 2017-06-25= value = 25.0}} 
+3
source

This can be done using the toMap collector:

 Map<Date, Thing> thingsByDate = things.stream().collect(Collectors.toMap( Thing::getActivityDate, Function.identity(), (thing1, thing2) -> new Thing(null, thing1.getActivityDate(), thing1.getValue()+thing2.getValue()) ); 

Then you can make this card as you wish.

+2
source

Source: https://habr.com/ru/post/1269206/


All Articles