Stream.min / Stream.max în Java

Găsesc cel mai mic și cel mai mare element după un Comparator; rezultatul este un Optional.

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

Ce face Stream.min / Stream.max

min(comparator) și max(comparator) parcurg stream-ul și returnează elementul cel mai mic, respectiv cel mai mare, după regula comparatorului. Spre deosebire de IntStream.max(), aici comparatorul este obligatoriu.

Rezultatul este un Optional<T>, gol când stream-ul nu are elemente. Scoți valoarea cu orElse, orElseThrow sau ifPresent. Dacă mai multe elemente sunt la egalitate, se returnează unul dintre ele (la stream-uri ordonate, primul pentru min).

Parametri

Parametru Descriere
comparator Regula de comparare: Comparator.naturalOrder(), Comparator.comparing(...) etc.

Ce returnează

Un Optional<T> cu elementul găsit sau gol.

Exemple

Exemplul 1: Cel mai ieftin și cel mai scump produs

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

public class Main {
    record Produs(String nume, double pret) {}

    public static void main(String[] args) {
        List<Produs> produse = List.of(
                new Produs("Laptop", 3200), new Produs("Mouse", 80),
                new Produs("Monitor", 950), new Produs("Cablu", 25));

        produse.stream().min(Comparator.comparingDouble(Produs::pret))
                .ifPresent(p -> System.out.println("Cel mai ieftin: " + p.nume()));
        Produs scump = produse.stream().max(Comparator.comparingDouble(Produs::pret)).orElseThrow();
        System.out.println("Cel mai scump: " + scump.nume() + " (" + scump.pret() + " lei)");
    }
}

Rezultat

Cel mai ieftin: Cablu
Cel mai scump: Laptop (3200.0 lei)

Exemplul 2: Texte și stream gol

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

public class Main {
    public static void main(String[] args) {
        List<String> orase = List.of("Iași", "Cluj-Napoca", "Arad", "Sibiu");
        System.out.println(orase.stream().min(Comparator.naturalOrder()).orElse("-"));
        System.out.println(orase.stream().max(Comparator.comparingInt(String::length)).orElse("-"));

        List<String> gol = List.of();
        System.out.println(gol.stream().max(Comparator.naturalOrder()));
        System.out.println(gol.stream().max(Comparator.naturalOrder()).orElse("niciun oraș"));
    }
}

Rezultat

Arad
Cluj-Napoca
Optional.empty
niciun oraș

Greșeli frecvente

  • Apelezi get() pe Optional fără să verifici. Pentru un stream gol primești NoSuchElementException.
  • Folosești max(Integer::compare) pe un Stream<Integer> și apoi min(Integer::max). Integer::max nu este un comparator (returnează valoarea, nu semnul) și dă rezultate greșite; folosește Integer::compare sau Comparator.naturalOrder().

Comenzi înrudite

  • Stream.sorted: Sortează elementele stream-ului, în ordinea naturală sau după un Comparator.
  • IntStream.sum: sum adună numerele din IntStream; average dă media lor ca OptionalDouble (gol dacă nu există numere).
  • Collectors.reducing: Varianta de colector a lui reduce: combină elementele două câte două; util ca downstream în groupingBy.
  • Stream.reduce: Combină toate elementele într-o singură valoare, aplicând o operație pas cu pas (sumă, produs, maxim, concatenare).