0Pricing
Java Academy · Aula

groupingBy: Classificação de Elementos

Agrupe elementos de fluxos em mapas por uma função classificadora e componha o resultado com coletores subsequentes.

groupingBy: Classificação de Elementos é uma aula grátis de Java Academy no CoddyKit. Esta é a aula 1 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Java Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Java Academy inclui 4 aulas no total.

O que é groupingBy?

Collectors.groupingBy() particiona os elementos do fluxo em um Map, no qual cada chave corresponde a uma lista de elementos correspondentes. É o equivalente, em fluxos, ao GROUP BY do SQL.

import java.util.*;
import java.util.stream.*;

record Person(String name, String city) {}
List<Person> people = List.of(
    new Person("Alice","NYC"), new Person("Bob","LA"),
    new Person("Carol","NYC"), new Person("Dave","LA"),
    new Person("Eve","Chicago")
);

Map<String, List<Person>> byCity =
    people.stream().collect(Collectors.groupingBy(Person::city));
byCity.forEach((city, ps) -> System.out.println(city + ": " + ps.size()));

Coletor subsequente: counting

Componha groupingBy com um coletor subsequente para agregar os dados em vez de listá-los:

Map<String, Long> countByCity =
    people.stream().collect(
        Collectors.groupingBy(Person::city, Collectors.counting())
    );
countByCity.forEach((city, n) -> System.out.println(city + " -> " + n));
// NYC -> 2, LA -> 2, Chicago -> 1

Coletor subsequente: mapping

Use Collectors.mapping() como coletor subsequente para transformar os elementos antes de coletá-los:

Map<String, List<String>> namesByCity =
    people.stream().collect(
        Collectors.groupingBy(
            Person::city,
            Collectors.mapping(Person::name, Collectors.toList())
        )
    );
namesByCity.forEach((city, names) -> System.out.println(city + ": " + names));

Coletor subsequente: joining

Concatene os nomes de cada grupo em uma única cadeia de caracteres separada por vírgulas:

Map<String, String> joinedByCity =
    people.stream().collect(
        Collectors.groupingBy(
            Person::city,
            Collectors.mapping(Person::name, Collectors.joining(", "))
        )
    );
joinedByCity.forEach((city, s) -> System.out.println(city + ": " + s));
// NYC: Alice, Carol

groupingBy em vários níveis

Aninhe chamadas de groupingBy para fazer uma classificação multidimensional:

record Employee(String name, String dept, String level) {}
List<Employee> emps = List.of(
    new Employee("A","Eng","Junior"), new Employee("B","Eng","Senior"),
    new Employee("C","HR","Junior"), new Employee("D","HR","Senior")
);

Map<String, Map<String, List<Employee>>> grouped =
    emps.stream().collect(
        Collectors.groupingBy(Employee::dept,
            Collectors.groupingBy(Employee::level))
    );
grouped.forEach((dept, levels) -> levels.forEach((level, list) ->
    System.out.println(dept+"/"+level+": "+list.size())));

Controlando o tipo de Map

Por padrão, groupingBy produz um HashMap. Use a sobrecarga de três argumentos para especificar outro tipo de mapa, como TreeMap para obter chaves ordenadas:

Map<String, Long> sorted =
    people.stream().collect(
        Collectors.groupingBy(Person::city, TreeMap::new, Collectors.counting())
    );
System.out.println(sorted); // keys in alphabetical order

Subsequente: averagingInt

Calcule médias por grupo:

record Product(String category, int price) {}
List<Product> products = List.of(
    new Product("A",10), new Product("A",20),
    new Product("B",15), new Product("B",25)
);

Map<String, Double> avgPrice =
    products.stream().collect(
        Collectors.groupingBy(Product::category,
            Collectors.averagingInt(Product::price))
    );
avgPrice.forEach((cat, avg) -> System.out.printf("%s: %.1f%n", cat, avg));

Subsequente: toUnmodifiableList

Use Collectors.toUnmodifiableList() como coletor subsequente para produzir grupos imutáveis:

Map<String, List<String>> immutable =
    people.stream().collect(
        Collectors.groupingBy(Person::city,
            Collectors.mapping(Person::name, Collectors.toUnmodifiableList()))
    );
// Attempting to modify throws UnsupportedOperationException

Caso real: resumo de pedidos

Agrupe os pedidos por status e some os valores de cada grupo:

record Order(String status, double amount) {}
List<Order> orders = List.of(
    new Order("PAID", 50.0), new Order("PENDING", 30.0),
    new Order("PAID", 75.0), new Order("CANCELLED", 20.0)
);

Map<String, Double> totalByStatus =
    orders.stream().collect(
        Collectors.groupingBy(Order::status,
            Collectors.summingDouble(Order::amount))
    );
totalByStatus.forEach((s, t) -> System.out.printf("%s: $%.2f%n", s, t));

Considerações de desempenho

groupingBy coleta todos os elementos na memória. Para conjuntos de dados muito grandes, considere processá-los em blocos ou usar um GROUP BY no nível do banco de dados. O coletor subsequente é executado para cada elemento — mantenha-o leve para evitar um comportamento O(n²).

Combinando filter e sorted

Encadeie operações do fluxo antes da coleta para filtrar ou ordenar previamente os dados:

Map<String, Long> activeCities =
    people.stream()
          .filter(p -> !p.city().equals("Chicago"))
          .collect(Collectors.groupingBy(Person::city, Collectors.counting()));
System.out.println(activeCities); // {NYC=2, LA=2}

Verificação rápida

Que tipo Collectors.groupingBy(Person::city) produz quando usado com collect()?

Recapitulação: groupingBy

Principais pontos:

  • groupingBy(classifier) → Map<K, List<T>>
  • Componha com coletores subsequentes: counting, mapping, joining e resumo estatístico
  • Aninhe groupingBy para fazer uma classificação multidimensional
  • Use a sobrecarga de três argumentos para controlar o tipo do mapa resultante, como TreeMap

Perguntas Frequentes

A aula “groupingBy: Classificação de Elementos” é grátis?

Sim — o texto completo de “groupingBy: Classificação de Elementos” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Java Academy, atualize para CoddyKit PRO. O curso de Java Academy inclui 4 aulas no total.

O que vou aprender em “groupingBy: Classificação de Elementos”?

Agrupe elementos de fluxos em mapas por uma função classificadora e componha o resultado com coletores subsequentes. Você pratica Java Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Java Academy?

Nenhuma experiência prévia é necessária. Java Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 4.

Quanto tempo leva a aula “groupingBy: Classificação de Elementos”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Java Academy?

Sim. Cada aula de Java Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. groupingBy: Classificação de Elementos
  2. partitioningBy e Contagem
  3. toMap, joining e summarizing
  4. Construção de um Collector Personalizado
← Voltar para Java Academy