Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 854
OanaV. Avatar asked May 15 '17 18:05

OanaV.


People also ask

What is stream map () in Java?

Introduction Stream map () is an intermediate operation used to apply one given function to the elements of a stream. It takes one function as its argument and applies it to each value of the stream and returns one fresh stream. In this tutorial, we will learn how to use the Java Streams map function with different examples.

How to sum all the elements in an IntStream in Java?

An IntStream has a sum method to sum all the elements in the stream (which are primitive integers). Note: List.of method was added in Java 9 as part of the many Collection factory methods. If you are using Java 8 or less, use Arrays.asList in place of it. In the above example, calling stream returns a stream of integers ( Stream<Integer> ).

How to sum a stream of numbers using maptodouble?

mapToDouble takes a ToDoubleFunction. The ToDoubleFunction has a single method called applyAsDouble to map an element to a primitive double. The second way by which we can sum a stream of numbers is to use the reduce method on the stream.

How to calculate the sum of values of a map<object>?

To calculate the sum of values of a Map<Object, Integer> data structure, first we create a stream from the values of that Map. Next we apply one of the methods we used previously. For instance, by using IntStream.sum (): Integer sum = map.values ().stream ().mapToInt (Integer::valueOf).sum ();


1 Answers

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);
}
like image 162
Misha Avatar answered Nov 15 '22 07:11

Misha