Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Aprenda Agregando Elementos com o Método reduce() | Operações Terminais na Stream API
Stream API

bookAgregando Elementos com o Método reduce()

Ao trabalhar com coleções em Java, frequentemente é necessário reduzir todos os elementos a um único resultado, como uma soma, produto ou outro valor agregado.

Existem três variações do método reduce(), cada uma projetada para diferentes cenários. Vamos analisar cada uma em detalhes.

reduce() com um único parâmetro

Se for necessário agregar elementos sem um valor inicial, pode-se utilizar esta versão do reduce(). No entanto, como o stream pode estar vazio, o método retorna um Optional<T>.

Optional<T> reduce(BinaryOperator<T> accumulator);

Este método aplica a função accumulator a todos os elementos do stream e retorna um Optional<T>.

Exemplo Prático

Imagine uma loja online com uma lista de produtos e seus preços. O objetivo é calcular a receita total de todos os produtos da loja.

Main.java

Main.java

copy
1234567891011121314151617181920212223242526272829303132333435363738
package com.example; import java.util.List; import java.util.Optional; public class Main { public static void main(String[] args) { List<Product> products = List.of( new Product("Laptop", 1200.0), new Product("Mouse", 25.0), new Product("Keyboard", 75.0) ); Optional<Double> totalRevenue = products.stream() .map(Product::getPrice) .reduce(Double::sum); totalRevenue.ifPresent(revenue -> System.out.println("Total revenue: " + revenue)); } } class Product { private String name; private double price; public Product(String name, double price) { this.name = name; this.price = price; } public String getName() { return name; } public double getPrice() { return price; } }

Este código cria uma lista de produtos e, em seguida, utiliza o reduce() para somar os preços. O método map(Product::getPrice) extrai o preço de cada produto, enquanto Double::sum realiza a soma. Se o resultado estiver presente, ele é impresso.

reduce() com Dois Parâmetros

Para garantir um valor de retorno mesmo quando o stream está vazio, utilize o método reduce() com um parâmetro de identidade. O valor inicial assegura um cálculo estável.

T reduce(T identity, BinaryOperator<T> accumulator);

Esta versão do reduce() inicia com o valor identity fornecido, garantindo que um resultado seja sempre retornado, mesmo para um stream vazio.

Exemplo prático

Suponha que uma loja possua um caixa com um saldo inicial, e seja necessário somar o preço total de todos os produtos para determinar o potencial total em caixa disponível.

Main.java

Main.java

copy
12345678910111213141516171819202122232425262728293031323334353637
package com.example; import java.util.List; public class Main { public static void main(String[] args) { List<Product> products = List.of( new Product("Laptop", 1200.0), new Product("Mouse", 25.0), new Product("Keyboard", 75.0) ); double totalRevenue = products.stream() .map(Product::getPrice) .reduce(500.0, Double::sum); System.out.println("Total revenue with initial balance: " + totalRevenue); } } class Product { private String name; private double price; public Product(String name, double price) { this.name = name; this.price = price; } public String getName() { return name; } public double getPrice() { return price; } }

Aqui, o código extrai os preços com map(Product::getPrice) e aplica reduce(500.0, Double::sum), onde 500.0 representa o saldo inicial, e Double::sum soma os valores.

reduce() para Processamento Paralelo

Esta versão de reduce() é projetada para casos em que são necessárias transformações mais complexas e os resultados precisam ser agregados em paralelo.

<U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner);

Este método recebe três parâmetros:

  • identity – o valor inicial;
  • accumulator – uma função que transforma cada elemento;
  • combiner – uma função que mescla os resultados parciais.

Exemplo Prático

Em uma loja online, é necessário calcular o número total de caracteres em todos os nomes dos produtos. Isso pode ser útil para definir limites no comprimento do recibo.

Main.java

Main.java

copy
123456789101112131415161718192021222324252627282930313233343536
package com.example; import java.util.List; public class Main { public static void main(String[] args) { List<Product> products = List.of( new Product("Laptop", 1200.0), new Product("Mouse", 25.0), new Product("Keyboard", 75.0) ); int totalLength = products.stream() .reduce(0, (sum, product) -> sum + product.getName().length(), Integer::sum); System.out.println("Total name length: " + totalLength); } } class Product { private String name; private double price; public Product(String name, double price) { this.name = name; this.price = price; } public String getName() { return name; } public double getPrice() { return price; } }

O código percorre a lista de produtos utilizando o reduce(), onde 0 é o valor inicial, (sum, product) -> sum + product.getName().length() define a lógica para somar os comprimentos dos nomes dos produtos, e Integer::sum combina os resultados em um ambiente de processamento paralelo.

1. Qual tipo de dado o método reduce(BinaryOperator<T> accumulator) retorna se o stream puder estar vazio?

2. Quando deve-se usar reduce(T identity, BinaryOperator<T> accumulator)?

question mark

Qual tipo de dado o método reduce(BinaryOperator<T> accumulator) retorna se o stream puder estar vazio?

Select the correct answer

question mark

Quando deve-se usar reduce(T identity, BinaryOperator<T> accumulator)?

Select the correct answer

Tudo estava claro?

Como podemos melhorá-lo?

Obrigado pelo seu feedback!

Seção 3. Capítulo 6

Pergunte à IA

expand

Pergunte à IA

ChatGPT

Pergunte o que quiser ou experimente uma das perguntas sugeridas para iniciar nosso bate-papo

Awesome!

Completion rate improved to 2.33

bookAgregando Elementos com o Método reduce()

Deslize para mostrar o menu

Ao trabalhar com coleções em Java, frequentemente é necessário reduzir todos os elementos a um único resultado, como uma soma, produto ou outro valor agregado.

Existem três variações do método reduce(), cada uma projetada para diferentes cenários. Vamos analisar cada uma em detalhes.

reduce() com um único parâmetro

Se for necessário agregar elementos sem um valor inicial, pode-se utilizar esta versão do reduce(). No entanto, como o stream pode estar vazio, o método retorna um Optional<T>.

Optional<T> reduce(BinaryOperator<T> accumulator);

Este método aplica a função accumulator a todos os elementos do stream e retorna um Optional<T>.

Exemplo Prático

Imagine uma loja online com uma lista de produtos e seus preços. O objetivo é calcular a receita total de todos os produtos da loja.

Main.java

Main.java

copy
1234567891011121314151617181920212223242526272829303132333435363738
package com.example; import java.util.List; import java.util.Optional; public class Main { public static void main(String[] args) { List<Product> products = List.of( new Product("Laptop", 1200.0), new Product("Mouse", 25.0), new Product("Keyboard", 75.0) ); Optional<Double> totalRevenue = products.stream() .map(Product::getPrice) .reduce(Double::sum); totalRevenue.ifPresent(revenue -> System.out.println("Total revenue: " + revenue)); } } class Product { private String name; private double price; public Product(String name, double price) { this.name = name; this.price = price; } public String getName() { return name; } public double getPrice() { return price; } }

Este código cria uma lista de produtos e, em seguida, utiliza o reduce() para somar os preços. O método map(Product::getPrice) extrai o preço de cada produto, enquanto Double::sum realiza a soma. Se o resultado estiver presente, ele é impresso.

reduce() com Dois Parâmetros

Para garantir um valor de retorno mesmo quando o stream está vazio, utilize o método reduce() com um parâmetro de identidade. O valor inicial assegura um cálculo estável.

T reduce(T identity, BinaryOperator<T> accumulator);

Esta versão do reduce() inicia com o valor identity fornecido, garantindo que um resultado seja sempre retornado, mesmo para um stream vazio.

Exemplo prático

Suponha que uma loja possua um caixa com um saldo inicial, e seja necessário somar o preço total de todos os produtos para determinar o potencial total em caixa disponível.

Main.java

Main.java

copy
12345678910111213141516171819202122232425262728293031323334353637
package com.example; import java.util.List; public class Main { public static void main(String[] args) { List<Product> products = List.of( new Product("Laptop", 1200.0), new Product("Mouse", 25.0), new Product("Keyboard", 75.0) ); double totalRevenue = products.stream() .map(Product::getPrice) .reduce(500.0, Double::sum); System.out.println("Total revenue with initial balance: " + totalRevenue); } } class Product { private String name; private double price; public Product(String name, double price) { this.name = name; this.price = price; } public String getName() { return name; } public double getPrice() { return price; } }

Aqui, o código extrai os preços com map(Product::getPrice) e aplica reduce(500.0, Double::sum), onde 500.0 representa o saldo inicial, e Double::sum soma os valores.

reduce() para Processamento Paralelo

Esta versão de reduce() é projetada para casos em que são necessárias transformações mais complexas e os resultados precisam ser agregados em paralelo.

<U> U reduce(U identity, BiFunction<U, ? super T, U> accumulator, BinaryOperator<U> combiner);

Este método recebe três parâmetros:

  • identity – o valor inicial;
  • accumulator – uma função que transforma cada elemento;
  • combiner – uma função que mescla os resultados parciais.

Exemplo Prático

Em uma loja online, é necessário calcular o número total de caracteres em todos os nomes dos produtos. Isso pode ser útil para definir limites no comprimento do recibo.

Main.java

Main.java

copy
123456789101112131415161718192021222324252627282930313233343536
package com.example; import java.util.List; public class Main { public static void main(String[] args) { List<Product> products = List.of( new Product("Laptop", 1200.0), new Product("Mouse", 25.0), new Product("Keyboard", 75.0) ); int totalLength = products.stream() .reduce(0, (sum, product) -> sum + product.getName().length(), Integer::sum); System.out.println("Total name length: " + totalLength); } } class Product { private String name; private double price; public Product(String name, double price) { this.name = name; this.price = price; } public String getName() { return name; } public double getPrice() { return price; } }

O código percorre a lista de produtos utilizando o reduce(), onde 0 é o valor inicial, (sum, product) -> sum + product.getName().length() define a lógica para somar os comprimentos dos nomes dos produtos, e Integer::sum combina os resultados em um ambiente de processamento paralelo.

1. Qual tipo de dado o método reduce(BinaryOperator<T> accumulator) retorna se o stream puder estar vazio?

2. Quando deve-se usar reduce(T identity, BinaryOperator<T> accumulator)?

question mark

Qual tipo de dado o método reduce(BinaryOperator<T> accumulator) retorna se o stream puder estar vazio?

Select the correct answer

question mark

Quando deve-se usar reduce(T identity, BinaryOperator<T> accumulator)?

Select the correct answer

Tudo estava claro?

Como podemos melhorá-lo?

Obrigado pelo seu feedback!

Seção 3. Capítulo 6
some-alt