Atualizado: 21/09/2025

Este conteúdo é original e não foi gerado por inteligência artificial.

Métodos de Agregação na Stream API: Agregando Resultados

Os métodos de agregação (ou de redução) são métodos terminais que processam todos os elementos de um stream para produzir um único resultado. Esse resultado pode ser um valor primitivo (como uma contagem), um objeto específico do stream (como o elemento de menor valor) ou um booleano.

Contagem de Elementos: count

O método count() é um método terminal simples que retorna a quantidade de elementos no stream como um long.

import java.util.List;

public class Program {
    public static void main(String[] args) {
        List<String> names = List.of("Tom", "Sam", "Bob", "Alice");

        // Conta todos os elementos no stream
        long totalCount = names.stream().count();
        System.out.println(totalCount);  // Saída: 4

        // Conta apenas os elementos que atendem a uma condição
        long filteredCount = names.stream().filter(n -> n.length() <= 3).count();
        System.out.println(filteredCount);  // Saída: 3
    }
}

Buscando Elementos: findFirst e findAny

Os métodos findFirst() e findAny() são usados para extrair um elemento do stream. Ambos retornam o resultado encapsulado em um objeto Optional, pois o stream pode estar vazio.

  • findFirst(): Retorna o primeiro elemento do stream. É um método determinístico.
  • findAny(): Retorna qualquer elemento do stream. Em streams sequenciais, geralmente retorna o primeiro, mas em streams paralelos, pode retornar qualquer elemento que seja processado primeiro, otimizando a performance.
import java.util.List;
import java.util.Optional;

public class Program {
    public static void main(String[] args) {
        List<String> names = List.of("Tom", "Sam", "Bob", "Alice");

        Optional<String> first = names.stream().findFirst();
        first.ifPresent(name -> System.out.println("Primeiro elemento: " + name)); // Saída: Tom

        Optional<String> any = names.stream().findAny();
        any.ifPresent(name -> System.out.println("Qualquer elemento: " + name)); // Saída: Tom
    }
}

Nota sobre Optional: É uma boa prática usar métodos como ifPresent() ou orElse() para lidar com o valor de um Optional de forma segura, evitando NullPointerException. Chamar get() diretamente em um Optional vazio resultará em uma exceção.

Verificação de Condições: allMatch, anyMatch, noneMatch

Este grupo de métodos terminais de curto-circuito verifica se os elementos do stream correspondem a um predicado e retorna um boolean.

  • anyMatch(predicate): Retorna true se pelo menos um elemento corresponder à condição. Para ao encontrar o primeiro.
  • allMatch(predicate): Retorna true se todos os elementos corresponderem à condição. Para ao encontrar o primeiro que não corresponde.
  • noneMatch(predicate): Retorna true se nenhum elemento corresponder à condição. Para ao encontrar o primeiro que corresponde.
import java.util.List;

public class Program {
    public static void main(String[] args) {
        List<String> names = List.of("Tom", "Sam", "Bob", "Alice");

        // Existe alguma string com mais de 3 caracteres?
        boolean any = names.stream().anyMatch(s -> s.length() > 3);
        System.out.println("anyMatch: " + any);    // true

        // Todas as strings têm exatamente 3 caracteres?
        boolean all = names.stream().allMatch(s -> s.length() == 3);
        System.out.println("allMatch: " + all);    // false

        // Nenhuma string é igual a "Bill"?
        boolean none = names.stream().noneMatch(s -> s.equals("Bill"));
        System.out.println("noneMatch: " + none);   // true
    }
}

Encontrando Mínimos e Máximos: min e max

Os métodos min() e max() retornam, respectivamente, o menor e o maior elemento do stream de acordo com um critério de comparação fornecido. Como o stream pode conter qualquer tipo de objeto, é necessário passar um Comparator para definir como os elementos devem ser comparados.

Optional<T> min(Comparator<? super T> comparator)
Optional<T> max(Comparator<? super T> comparator)

Ambos retornam um Optional, pois o stream pode estar vazio.

Para um stream de números, a comparação é direta:

import java.util.List;
import java.util.Optional;

public class Program {
    public static void main(String[] args) {
        List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9);

        Optional<Integer> min = numbers.stream().min(Integer::compare);
        Optional<Integer> max = numbers.stream().max(Integer::compare);

        min.ifPresent(val -> System.out.println("Min: " + val)); // Saída: 1
        max.ifPresent(val -> System.out.println("Max: " + val)); // Saída: 9
    }
}

Aqui, Integer::compare é uma referência de método que atua como o Comparator.

Para objetos mais complexos, a abordagem moderna é usar os métodos de fábrica da classe Comparator.

import java.util.Comparator;
import java.util.List;

class Phone {
    private String name;
    private int price;

    public Phone(String name, int price) { /* ... */ }
    public String getName() { return name; }
    public int getPrice() { return price;}
}

public class Program {
    public static void main(String[] args) {
        List<Phone> phones = List.of(
            new Phone("iPhone 15", 999),
            new Phone("Nokia G42", 250),
            new Phone("Samsung Galaxy S24", 899),
            new Phone("Pixel 8", 799)
        );

        // Encontra o telefone mais barato e o mais caro usando Comparator.comparingInt
        phones.stream()
              .min(Comparator.comparingInt(Phone::getPrice))
              .ifPresent(p -> System.out.printf("MIN: %s, Price: %d\n", p.getName(), p.getPrice()));

        phones.stream()
              .max(Comparator.comparingInt(Phone::getPrice))
              .ifPresent(p -> System.out.printf("MAX: %s, Price: %d\n", p.getName(), p.getPrice()));
    }
}

Neste exemplo, Comparator.comparingInt(Phone::getPrice) cria um Comparator que compara os objetos Phone com base no valor retornado pelo método getPrice. Esta é a forma preferida e mais legível para realizar comparações.

A saída será:

MIN: Nokia G42, Price: 250
MAX: iPhone 15, Price: 999

Resumo

  • count(): Retorna a quantidade de elementos no stream.
  • findFirst() / findAny(): Retornam um elemento do stream encapsulado em um Optional.
  • anyMatch() / allMatch() / noneMatch(): Verificam se os elementos atendem a uma condição e retornam um boolean. São métodos de curto-circuito.
  • min(c) / max(c): Retornam o menor ou o maior elemento de acordo com um Comparator fornecido, também em um Optional.
Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com