OanaV.
OanaV.

Reputation: 81

How map from a stream the sum of a Duration field in java?

I am trying to create a map that holds an activity and the total duration of that activity, knowing that the activity appears more times with different durations.

Normally, I would have solved it like this:

Map<String,Duration> result2 = new HashMap<String,Duration>();
     for(MonitoredData m: lista)
     {
         if(result2.containsKey(m.getActivity())) result2.replace(m.getActivity(),result2.get(m.getActivity()).plus(m.getDuration()));
         else result2.put(m.getActivity(), m.getDuration());
     }

But I am trying to do this with a stream, but I can't figure out how to put the sum in there.

Function<Duration, Duration> totalDuration = x -> x.plus(x);
Map<String, Duration> result2 = lista.stream().collect(
                        Collectors.groupingBy(MonitoredData::getActivity,
                                Collectors.groupingBy(totalDuration.apply(), Collectors.counting()))
                );

I tried in various ways to group them, to map them directly, or to sum them directly in the brackets, but i'm stuck.

Upvotes: 5

Views: 1598

Answers (1)

Misha
Misha

Reputation: 28173

Use the 3-argument version of toMap collector:

import static java.util.stream.Collectors.toMap;

Map<String,Duration> result = lista.stream()
    .collect(toMap(MonitoredData::getActivity, MonitoredData::getDuration, Duration::plus));

Also, note that Map interface got some nice additions in Java 8. One of them is merge. With that, even your iterative for loop can be rewritten to be much cleaner:

for (MonitoredData m: lista) {
    result.merge(m.getActivity(), m.getDuration(), Duration::plus);
}

Upvotes: 5

Related Questions