Ce face Stream.iterate
Stream.iterate(start, pas) produce start, pas(start), pas(pas(start)) și așa mai departe, la nesfârșit. Pentru a-l opri folosești limit(n) sau takeWhile.
Varianta cu trei argumente, iterate(start, conditie, pas), seamănă cu o buclă for: se oprește singură când condiția devine falsă. Este cea mai sigură variantă.
Stream.generate(furnizor) cere fiecare element unui Supplier, fără legătură cu elementul anterior: valori constante, numere aleatorii, citiri dintr-o sursă. Și acest stream este infinit, deci are nevoie de limit.
Parametri
| Parametru | Descriere |
|---|---|
start |
Primul element. |
continua |
Condiția verificată înaintea fiecărui element; când este falsă, stream-ul se oprește. |
pas |
Funcția care calculează următorul element din cel curent. |
furnizor |
Pentru generate: un Supplier chemat pentru fiecare element. |
Ce returnează
Un Stream<T> infinit (sau finit, pentru varianta cu condiție).
Exemple
Exemplul 1: Puterile lui 2 și o buclă for cu stream
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
// infinit, oprit cu limit
System.out.println(Stream.iterate(1, x -> x * 2).limit(10).toList());
// ca un for (int i = 0; i < 20; i += 5)
Stream.iterate(0, i -> i < 20, i -> i + 5)
.forEach(i -> System.out.println("i = " + i));
}
}
Rezultat
[1, 2, 4, 8, 16, 32, 64, 128, 256, 512]
i = 0
i = 5
i = 10
i = 15
Exemplul 2: Economii lunare cu dobândă
Fiecare element este calculat din cel anterior: suma crește cu 2% în fiecare lună.
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
Stream.iterate(1000.0, suma -> suma * 1.02)
.limit(6)
.forEach(suma -> System.out.printf("%.2f lei%n", suma));
}
}
Rezultat
1000.00 lei
1020.00 lei
1040.40 lei
1061.21 lei
1082.43 lei
1104.08 lei
Exemplul 3: generate: valori care nu depind de cele anterioare
Cu un Random cu seed fix, numerele sunt aceleași la fiecare rulare. Fără seed ar fi altele de fiecare dată.
import java.util.Random;
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
System.out.println(Stream.generate(() -> "-").limit(10).toList());
Random zar = new Random(7);
System.out.println(Stream.generate(() -> zar.nextInt(1, 7)).limit(8).toList());
}
}
Rezultat
[-, -, -, -, -, -, -, -, -, -]
[5, 3, 4, 5, 5, 5, 5, 6]
Greșeli frecvente
- Uiți
limitpe un stream infinit și apelezitoList()sauforEach. Programul rulează la nesfârșit sau rămâne fără memorie. - Pui
filterîn loc de condiția de oprire:iterate(1, x -> x + 1).filter(x -> x < 10)nu se oprește niciodată, pentru căfilterdoar sare peste elemente. Folosește varianta cu trei argumente sautakeWhile.
Comenzi înrudite
Stream.limit: limit păstrează doar primele n elemente, iar skip sare peste primele n.Stream.takeWhile: takeWhile ia elemente cât timp condiția e adevărată și se oprește la primul care nu o respectă; dropWhile le sare pe acestea.Supplier: Un „furnizor” de valori: nu primește nimic și returnează o valoare când apelezi get; util pentru valori create la nevoie.UnaryOperator: O Function în care intrarea și ieșirea au același tip (T → T); folosită de List.replaceAll și Stream.iterate.IntStream.range: Creează șirul de numere întregi dintre două limite: range fără ultima valoare, rangeClosed cu ea inclusă.