List.ofLazy în Java

Liste (List, ArrayList, LinkedList) JDK 27 (API în previzualizare)

Listă nemodificabilă a cărei valoare de la fiecare poziție se calculează abia la prima citire, apoi se păstrează.

Sintaxă
static <E> List<E> ofLazy(int size, IntFunction<? extends E> calcul)

Ce face List.ofLazy

List.ofLazy(n, calcul) creează o listă cu n poziții, dar nu calculează nimic la creare. Prima dată când citești poziția i, Java apelează calcul.apply(i) și păstrează rezultatul; citirile următoare îl returnează direct. Este util pentru valori scumpe de calculat, de care poate nu ai nevoie pe toate.

Lista este nemodificabilă și sigură între fire de execuție: chiar dacă două fire citesc aceeași poziție în același timp, calculul se face o singură dată. Funcția nu are voie să returneze null.

Atenție: în JDK 27 metoda face parte dintr-un API în previzualizare (preview, „lazy constants”). Se compilează și rulează doar cu --enable-preview (de exemplu javac --release 27 --enable-preview Main.java și java --enable-preview Main) și se poate schimba în versiunile următoare. Rezultatele de mai jos sunt dintr-o rulare reală cu aceste opțiuni.

Parametri

Parametru Descriere
size Numărul de poziții ale listei.
calcul Funcția care primește poziția și returnează valoarea (fără null).

Ce returnează

O listă nemodificabilă cu valori calculate la cerere.

Exemple

Exemplul 1: Valorile se calculează doar când sunt citite

La prima citire a poziției 3 apare mesajul „calculez 3”; la a doua citire nu mai apare. Afișarea întregii liste calculează restul pozițiilor.

import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<Integer> patrate = List.ofLazy(5, i -> {
            System.out.println("calculez " + i);
            return i * i;
        });
        System.out.println("Lista a fost creată.");
        System.out.println(patrate.get(3));
        System.out.println(patrate.get(3));
        System.out.println(patrate);
    }
}

Rezultat (rulat cu –enable-preview)

Lista a fost creată.
calculez 3
9
9
calculez 0
calculez 1
calculez 2
calculez 4
[0, 1, 4, 9, 16]

Exemplul 2: Rapoarte lunare calculate la cerere

import java.util.List;

public class Main {
    static String raport(int luna) {
        System.out.println("(generez raportul pentru luna " + (luna + 1) + ")");
        return "Raport luna " + (luna + 1) + ": vânzări " + (luna + 1) * 1000 + " lei";
    }

    public static void main(String[] args) {
        List<String> rapoarte = List.ofLazy(12, Main::raport);
        System.out.println(rapoarte.size() + " rapoarte disponibile");
        System.out.println(rapoarte.get(2));
        System.out.println(rapoarte.get(2));
    }
}

Rezultat (rulat cu –enable-preview)

12 rapoarte disponibile
(generez raportul pentru luna 3)
Raport luna 3: vânzări 3000 lei
Raport luna 3: vânzări 3000 lei

Greșeli frecvente

  • Compilezi fără --enable-preview: javac refuză cu mesajul că ofLazy este un API în previzualizare.
  • Pui în funcția de calcul efecte care trebuie să se întâmple de fiecare dată (de exemplu o numărătoare). Funcția rulează cel mult o dată pe poziție.
  • Returnezi null din funcție: citirea poziției aruncă NullPointerException.

Comenzi înrudite

  • List.of: Creează o listă nemodificabilă din valorile date (of) sau dintr-o copie a altei colecții (copyOf).
  • Set.ofLazy: Mulțime nemodificabilă formată din candidații care îndeplinesc o condiție; condiția se calculează abia când întrebi de un element.
  • Map.ofLazy: Map nemodificabil cu chei fixe, a cărui valoare pentru fiecare cheie se calculează abia la prima citire, apoi se păstrează.
  • List.get: get citește elementul de la o poziție; set îl înlocuiește și returnează valoarea veche.