Exemplo de lista de usuários:
Usuários com pontuação e se são moderadores ou não:
Usuario user1 = new Usuario("Paulo Silveira", 150, true);
Usuario user2 = new Usuario("Rodrigo Turini", 120, true);
Usuario user3 = new Usuario("Guilherme Silveira", 90);
Usuario user4 = new Usuario("Sergio Lopes", 120);
Usuario user5 = new Usuario("Adriano Almeida", 100);
List usuarios = Arrays.asList(user1, user2, user3, user4, user5);
Mapeando pontuação para lista de usuários:
Abordagem tradicional:
Usando HashMap e verificando a existência de uma lista para cada pontuação.
Adicionando os usuários a listas de pontuação:
Map
for(Usuario u: usuarios) {
if(!pontuacao.containsKey(u.getPontos())) {
pontuacao.put(u.getPontos(), new ArrayList<>());
}
pontuacao.get(u.getPontos()).add(u);
}
Exemplo de saída:
{
100=[Usuario Adriano Almeida],
150=[Usuario Paulo Silveira],
120=[Usuario Rodrigo Turini, Usuario Sergio Lopes],
90=[Usuario Guilherme Silveira]
}
Exemplo: ListaTradicional.java
Usando computeIfAbsent:
Usando Map.computeIfAbsent() para simplificar o código:
Map
for(Usuario u: usuarios) {
pontuacao.computeIfAbsent(u.getPontos(), user -> new ArrayList<>()).add(u);
}
Exemplo: ListaComputeIfAbsent.java
Usando Streams e groupingBy:
A solução mais funcional com Collectors.groupingBy:
Map
.collect(Collectors.groupingBy(Usuario::getPontos));
Particionando usuários em moderadores e não moderadores:
Usando partitioningBy para dividir usuários:
Map
.collect(Collectors.partitioningBy(Usuario::isModerador));
Exemplo de saída:
{
false=[Usuario Guilherme Silveira, Usuario Sergio Lopes, Usuario Adriano Almeida],
true=[Usuario Paulo Silveira, Usuario Rodrigo Turini]
}
Exemplo: ListaGroupPart.java
Usando mapping e toList para transformar os dados:
Gerando uma lista de nomes dos usuários por tipo:
Map
.collect(Collectors.partitioningBy(
Usuario::isModerador,
Collectors.mapping(Usuario::getNome, Collectors.toList())
));
Exemplo de saída:
{
false=[Guilherme Silveira, Sergio Lopes, Adriano Almeida],
true=[Paulo Silveira, Rodrigo Turini]
}
Somando pontos dos moderadores e não moderadores:
Usando summingInt para calcular a soma de pontos:
Map
.collect(Collectors.partitioningBy(
Usuario::isModerador,
Collectors.summingInt(Usuario::getPontos)
));
Exemplo de saída:
{false=310, true=270}
Concatenando nomes dos usuários:
Usando Collectors.joining() para concatenar nomes:
String nomes = usuarios.stream()
.map(Usuario::getNome)
.collect(Collectors.joining(", "));
Exemplo: NomePontoTipo.java
Vantagens do uso de coletores e streams:
Estilo funcional: Código mais enxuto e expressivo.
Menos efeitos colaterais: Favorece a imutabilidade das coleções originais.
Facilidade para paralelização: Menos mutabilidade facilita a execução paralela.