Somando números com Java Streams

Somando números com Java Streams

1. Introdução

Neste tutorial rápido, mostraremos várias maneiras decalculating the sum of integers,using the Stream API.

Para fins de simplicidade, usaremos números inteiros em nossos exemplos. No entanto, também podemos aplicar os mesmos métodos aos longos e duplos.

2. UsandoStream.reduce()

Stream.reduce() is a terminal operation thatperforms a reduction on the elements of the stream.

Ele aplica um operador binário (acumulador) a cada elemento no fluxo, onde o primeiro operando é o valor de retorno do aplicativo anterior e o segundo é o elemento de fluxo atual.

No primeiro método de usar o métodoreduce(), a função acumuladora é uma expressão lambda que adiciona dois valoresIntegere retorna um valorInteger:

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

Da mesma forma, podemos usar um jáexisting Java method:

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

Ou podemos definir e usar nosso método personalizado:

public class ArithmeticUtils {

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

Então, podemos passar esta função como um parâmetro para o métodoreduce():

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

3. UsandoStream.collect()

O segundo método para calcular a soma de uma lista de inteiros é usando a operação de terminalcollect():

List integers = Arrays.asList(1, 2, 3, 4, 5);
Integer sum = integers.stream()
  .collect(Collectors.summingInt(Integer::intValue));

Da mesma forma, a classeCollectors fornece os métodossummingLong()esummingDouble() para calcular as somas de longos e duplos, respectivamente.

4. UsandoIntStream.sum()

A API de fluxo nos fornece a operação intermediáriamapToInt(), que converte nosso fluxo em umIntStream object.

Este método leva um mapeador como parâmetro, que ele usa para fazer a conversão, então, podemos chamar o métodosum() para calcular a soma dos elementos do fluxo.

Vejamos um exemplo rápido de como podemos usá-lo:

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

Da mesma forma, podemos usar os métodosmapToLong()emapToDouble() para calcular as somas de longos e duplos, respectivamente.

5. UsandoStream#sum comMap

Para calcular a soma dos valores de uma estrutura de dadosMap<Object, Integer>, primeiro criamos umstream from the values desseMap, depois aplicamos um dos métodos que usamos anteriormente.

Por exemplo, usandoIntStream.sum():

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

6. UsandoStream#sum com objetos

Vamos imaginar que temos uma lista de objetos e que queremos calcularthe sum of all the values of a given field desses objetos.

Por exemplo:

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
}

A seguir, vamos imaginar que desejamos calcular o preço total de todos os itens da seguinte lista:

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 items = Arrays.asList(item1, item2, item3, item4);

Nesse caso, para calcular a soma usando os métodos mostrados nos exemplos anteriores, precisamos chamar o métodomap()to convert our stream into a stream of integers.

Como resultado, podemos usarStream.reduce(), Stream.collect(), and IntStream.sum() para calcular a soma:

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. UsandoStream#sum comString

Vamos supor que temos um objetoString contendo alguns inteiros.

Para calcular a soma desses inteiros, em primeiro lugar, precisamos deto convert that String into an Array, depois deto filter out the non-integer elements e, finalmente,convert the remaining elements dessa matriz em números.

Vamos ver todas essas etapas em ação:

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. Conclusão

Neste tutorial, vimos vários métodos de como calcular a soma de uma lista de números inteiros usando a API de fluxo. Além disso, usamos esses métodos para calcular a soma dos valores de um determinado campo de uma lista de objetos, a soma dos valores de um mapa, bem como os números dentro de um determinado objetoString.

Como sempre, o código completo está disponívelover on GitHub.