Estratégia com flatMap
Criar um Stream a partir de List:
Stream
.map(Payment::getProducts)
.flatMap(p -> p.stream());
Alternativa com method reference:
.flatMap(List::stream)
Forma ainda mais enxuta:
Stream
.flatMap(p -> p.getProducts().stream());
Observações:
Não há diferença significativa de performance entre as abordagens.
A escolha deve priorizar a legibilidade do código.
Contando quantas vezes cada produto foi vendido
Gerar Map com a contagem de cada produto:
Map
.flatMap(p -> p.getProducts().stream())
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
Impressão do Map:
- Print padrão pode gerar uma linha longa e difícil de ler:
System.out.println(topProducts);
- Melhor: imprimir cada entrada em linha separada:
topProducts.entrySet().stream()
.forEach(System.out::println);
Observação: Encadear o entrySet().stream() logo após o collect() impede o uso posterior do Map.
Encontrando o produto mais vendido
Usar max com Comparator baseado no valor:
topProducts.entrySet().stream()
.max(Comparator.comparing(Map.Entry::getValue))
.ifPresent(System.out::println);
max(...) retorna um Optional>
Por isso, o uso de .ifPresent(...)
Exemplo: PagamentosProdutosMaisVendidosExemplo.java