Problema com tipos primitivos:
Se os preços fossem int, seria possível usar mapToDouble(...).sum().
Com BigDecimal, isso não é possível diretamente.
Solução com reduce:
Usando expressão lambda:
.reduce((total, price) -> total.add(price))
Usando method reference (mais limpo):
.reduce(BigDecimal::add)
Tratando o retorno Optional:
.reduce(BigDecimal::add)
.ifPresent(System.out::println);
Forma alternativa com valor inicial:
- Evita Optional, retorna diretamente BigDecimal.
.reduce(BigDecimal.ZERO, BigDecimal::add)
Exemplo: ReduceExamples.java
Somando os valores de todos os pagamentos (payments)
Estratégia com map e reduce em duas etapas:
1 Gerar Stream de subtotais (Stream):
payments.stream()
.map(p -> p.getProducts().stream()
.map(Product::getPrice)
.reduce(BigDecimal.ZERO, BigDecimal::add))
2 Somar os subtotais:
.reduce(BigDecimal.ZERO, BigDecimal::add)
Alternativa com flatMap (mais limpa):
Criar um único Stream de todos os produtos:
payments.stream()
.flatMap(p -> p.getProducts().stream()
.map(Product::getPrice))
Explicação da função usada:
Function
p -> p.getProducts().stream().map(Product::getPrice);
obs.: Necessário usar flatMap para evitar Stream>.
Somando todos os valores diretamente:
.reduce(BigDecimal.ZERO, BigDecimal::add)
Exemplo: PagamentosReduceExemplos .java