Agregando 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
1234567891011121314151617181920212223242526272829303132333435363738package 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
12345678910111213141516171819202122232425262728293031323334353637package 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
123456789101112131415161718192021222324252627282930313233343536package 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)?
Obrigado pelo seu feedback!
Pergunte à IA
Pergunte à IA
Pergunte o que quiser ou experimente uma das perguntas sugeridas para iniciar nosso bate-papo
Awesome!
Completion rate improved to 2.33
Agregando 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
1234567891011121314151617181920212223242526272829303132333435363738package 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
12345678910111213141516171819202122232425262728293031323334353637package 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
123456789101112131415161718192021222324252627282930313233343536package 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)?
Obrigado pelo seu feedback!