Stream.forEach în Java

Rulează o acțiune (de obicei o afișare) pentru fiecare element; forEachOrdered păstrează ordinea și la stream-uri paralele.

Sintaxă
void forEach(Consumer<? super T> actiune)
void forEachOrdered(Consumer<? super T> actiune)

Ce face Stream.forEach

forEach(actiune) este o operație finală: pornește stream-ul și apelează acțiunea pentru fiecare element. Nu returnează nimic. Cel mai des acțiunea este System.out::println.

Pe un stream secvențial, ordinea este cea a sursei. Pe un stream paralel (parallelStream(), .parallel()), forEach nu garantează nicio ordine: elementele pot apărea amestecat. forEachOrdered garantează ordinea sursei, chiar și în paralel.

Dacă vrei să construiești o listă, nu adăuga elemente dintr-un forEach: folosește toList() sau collect.

Parametri

Parametru Descriere
actiune Un Consumer apelat pentru fiecare element.

Ce returnează

Nimic (void).

Exemple

Exemplul 1: Afișarea elementelor

import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> cumparaturi = List.of("pâine", "lapte", "ouă");
        cumparaturi.stream().forEach(System.out::println);

        cumparaturi.stream()
                .map(String::toUpperCase)
                .forEach(p -> System.out.println("- " + p));
    }
}

Rezultat

pâine
lapte
ouă
- PÂINE
- LAPTE
- OUĂ

Exemplul 2: forEachOrdered pe un stream paralel

Cu forEach în paralel, ordinea ar diferi de la o rulare la alta. forEachOrdered afișează mereu în ordinea listei.

import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> etape = List.of("comandă", "plată", "ambalare", "livrare", "recenzie");
        etape.parallelStream()
                .map(String::toUpperCase)
                .forEachOrdered(System.out::println);
    }
}

Rezultat

COMANDĂ
PLATĂ
AMBALARE
LIVRARE
RECENZIE

Exemplul 3: Numerotarea rândurilor

forEach nu dă indexul elementului. Pornești de la un IntStream de indici.

import java.util.List;
import java.util.stream.IntStream;

public class Main {
    public static void main(String[] args) {
        List<String> clasament = List.of("Ioana", "Radu", "Ana");
        IntStream.range(0, clasament.size())
                .forEach(i -> System.out.println((i + 1) + ". " + clasament.get(i)));
    }
}

Rezultat

1. Ioana
2. Radu
3. Ana

Greșeli frecvente

  • Folosești forEach pe un stream paralel și aștepți ordinea listei. Folosește forEachOrdered.
  • Adaugi elemente într-o ArrayList din forEach, mai ales în paralel. Nu este sigur pentru fire și este mai lung; folosește toList().
  • Încerci break sau return pentru a ieși din forEach. return doar trece la următorul element; pentru oprire folosește takeWhile, findFirst sau o buclă for.

Comenzi înrudite

  • Stream.peek: Rulează o acțiune pentru fiecare element care trece, fără să-l schimbe; folosit mai ales pentru depanare.
  • Consumer: O acțiune care primește o valoare și nu returnează nimic (afișează, salvează, trimite); o rulezi cu accept.
  • Stream.toList: Adună elementele stream-ului într-o listă care nu se poate modifica, sau într-un tablou cu toArray.
  • Stream.collect: Adună elementele într-un rezultat (listă, set, map, text) folosind un Collector, de obicei din clasa Collectors.