Java Top

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE

1. Introduction

In this quick tutorial, we’ll show various ways of calculating the sum of integers, using the Stream API.

For the sake of simplicity, we’ll use integers in our examples. However, we can apply the same methods to longs and doubles as well.

2. Using Stream.reduce()

Stream.reduce() is an intermediate operation that performs a reduction on the elements of the stream.

It applies a binary operator (accumulator) to each element in the stream, where the first operand is the return value of the previous application, and the second one is the current stream element.

In the first method of using the reduce() method, the accumulator function is a lambda expression that adds two Integer values and returns an Integer value:

List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
Integer sum = integers.stream()
  .reduce(0, (a, b) -> a + b);

In the same way, we can use an already existing Java method:

List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
Integer sum = integers.stream()
  .reduce(0, Integer::sum);

Or we can define and use our custom method:

public class ArithmeticUtils {

    public static int add(int a, int b) {
        return a + b;
    }
}

Then, we can pass this function as a parameter to the reduce() method:

List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
Integer sum = integers.stream()
  .reduce(0, ArithmeticUtils::add);

3. 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()
  .collect(Collectors.summingInt(Integer::intValue));

Similarly, the Collectors class provides summingLong() and summingDouble() methods to calculate the sums of longs and doubles respectively.

4. Using IntStream.sum()

The Stream API provides us with the mapToInt() intermediate operation, which converts our stream to an IntStream object.

This method takes a mapper as a parameter, which it uses to do the conversion, then, we can call the sum() method to calculate the sum of the stream’s elements.

Let’s see a quick example of how we can use it:

List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);
Integer sum = integers.stream()
  .mapToInt(Integer::intValue)
  .sum();

In the same fashion, we can use the mapToLong() and mapToDouble() methods to calculate the sums of longs and doubles respectively.

5. Using Stream#sum with Map

To calculate the sum of values of a Map<Object, Integer> data structure, firstly we create a stream from the values of that Map, then we apply one of the methods we used previously.

For instance, by using IntStream.sum():

Integer sum = map.values()
  .stream()
  .mapToInt(Integer::valueOf)
  .sum();

6. Using Stream#sum with Objects

Let’s imagine that we have a list of objects and that we want to calculate the sum of all the values of a given field of these objects.

For example:

public class Item {

    private int id;
    private Integer price;

    public Item(int id, Integer price) {
        this.id = id;
        this.price = price;
    }

    // Standard getters and setters
}

Next, let’s imagine that we want to calculate the total price of all the items of the following list:

Item item1 = new Item(1, 10);
Item item2 = new Item(2, 15);
Item item3 = new Item(3, 25);
Item item4 = new Item(4, 40);
        
List<Item> items = Arrays.asList(item1, item2, item3, item4);

In this case, in order to calculate the sum using the methods shown in previous examples, we need to call the map() method to convert our stream into a stream of integers.

As a result, we can use Stream.reduce(), Stream.collect(), and IntStream.sum() to calculate the sum:

Integer sum = items.stream()
  .map(x -> x.getPrice())
  .reduce(0, ArithmeticUtils::add);
Integer sum = items.stream()
  .map(x -> x.getPrice())
  .reduce(0, Integer::sum);
Integer sum = items.stream()
  .map(item -> item.getPrice())
  .reduce(0, (a, b) -> a + b);
Integer sum = items.stream()
  .map(x -> x.getPrice())
  .collect(Collectors.summingInt(Integer::intValue));
items.stream()
  .mapToInt(x -> x.getPrice())
  .sum();

7. Using Stream#sum with String

Let’s suppose that we have a String object containing some integers.

To calculate the sum of these integers, first of all, we need to convert that String into an Array, then we need to filter out the non-integer elements, and finally, convert the remaining elements of that array into numbers.

Let’s see all these steps in action:

String string = "Item1 10 Item2 25 Item3 30 Item4 45";

Integer sum = Arrays.stream(string.split(" "))
    .filter((s) -> s.matches("\\d+"))
    .mapToInt(Integer::valueOf)
    .sum();

8. Conclusion

In this tutorial, we saw several methods of how to calculate the sum of a list of integers by using the Stream API. Also, we used these methods to calculate the sum of values of a given field of a list of objects, the sum of the values of a map, as well as the numbers within a given String object.

As always, the complete code is available over on GitHub.

Java bottom

I just announced the new Learn Spring course, focused on the fundamentals of Spring 5 and Spring Boot 2:

>> CHECK OUT THE COURSE
newest oldest most voted
Notify of
Andrii Stoialtsev
Guest
Andrii Stoialtsev

Thanks for practical examples. You really don’t need to call super() method in Item constructor, though.

Loredana Crusoveanu
Editor

Good point, it’s the constructor generated by the IDE 🙂

I’ve removed the call to super().

Cheers.

Comments are closed on this article!