Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sum values in a Map with a stream?

I want the equivalent of this with a stream:

public static <T extends Number> T getSum(final Map<String, T> data) {     T sum = 0;     for (String key: data.keySet())         sum += data.get(key);     return sum; } 

This code doesn't actually compile because 0 cannot be assigned to type T, but you get the idea.

like image 537
Jay Avatar asked May 06 '15 23:05

Jay


People also ask

How do you sum in streams?

Using Stream.collect() The second method for calculating the sum of a list of integers is by using the collect() terminal operation: List<Integer> integers = Arrays. asList(1, 2, 3, 4, 5); Integer sum = integers. stream() .

How do you sum a value on a map?

To get the sum of all values in a Map :Initialize a sum variable and set it to 0 . Use the forEach() method to iterate over the Map . On each iteration, add the number to the sum , reassigning the variable.

Can stream be used with map?

Yes, you can map each entry to another temporary entry that will hold the key and the parsed integer value. Then you can filter each entry based on their value. Map<String, Integer> output = input.

How do you sum values in Java?

So you simply make this: sum=sum+num; for the cycle. For example sum is 0, then you add 5 and it becomes sum=0+5 , then you add 6 and it becomes sum = 5 + 6 and so on.


2 Answers

You can do this:

int sum = data.values().stream().mapToInt(Integer::parseInt).sum(); 
like image 107
Paul Boddington Avatar answered Sep 24 '22 12:09

Paul Boddington


Here's another way to do this:

int sum = data.values().stream().reduce(0, Integer::sum); 

(For a sum to just int, however, Paul's answer does less boxing and unboxing.)

As for doing this generically, I don't think there's a way that's much more convenient.

We could do something like this:

static <T> T sum(Map<?, T> m, BinaryOperator<T> summer) {     return m.values().stream().reduce(summer).get(); }  int sum = MyMath.sum(data, Integer::sum); 

But you always end up passing the summer. reduce is also problematic because it returns Optional. The above sum method throws an exception for an empty map, but an empty sum should be 0. Of course, we could pass the 0 too:

static <T> T sum(Map<?, T> m, T identity, BinaryOperator<T> summer) {     return m.values().stream().reduce(identity, summer); }  int sum = MyMath.sum(data, 0, Integer::sum); 
like image 21
Radiodef Avatar answered Sep 21 '22 12:09

Radiodef