Stream Collectors sú výkonnou funkciou v Java 8 Stream API, ktorá vám umožňuje efektívne zbierať a spracovávať dáta. Tu vysvetlíme ich štruktúru a ako sa dá použiť metóda Java collect().

Ako sa dá použiť Java collect()?

Stream Collector sa dá použiť na vytvorenie zoznamu, množiny alebo mapy zo streamu. Stream je sekvencia prvkov, ktoré sa spracúvajú jeden po druhom. Rozhranie Collector poskytuje súbor redukčných operácií pre dáta v streamovom potrubí. Ide o terminálne operácie, ktoré zbierajú a spájajú výsledky medzistupňov.

Kolektory sa dajú použiť na filtrovanie alebo triedenie objektov zo streamu. Je možné aj agregovanie, napríklad sčítanie čísel, kombinovanie reťazcov alebo počítanie prvkov. Okrem toho majú kolektory funkcie, ktoré dokážu transformovať obsah streamu do konkrétnej štruktúry. Môžete napríklad transformovať zoznam na mapu. Zoskupenia pomáhajú kategorizovať prvky s určitými vlastnosťami alebo podmienkami. Najdôležitejšie je, že zberače tokov majú tú výhodu, že môžu spracovávať dáta súčasne pomocou viacerých vlákien. To umožňuje vykonávať operácie oveľa rýchlejšie a efektívnejšie, najmä pri veľkých množstvách dát.

Aká je syntax pre Java collect()?

Metóda prijíma ako argument kolektor, ktorý popisuje, ako sa majú prvky toku zbierať a agregovať. Kolektor je rozhranie, ktoré poskytuje rôzne metódy na agregáciu prvkov toku do konkrétnej formy, napríklad do zoznamu, množiny alebo mapy.

Existujú dve varianty metódy Java Stream collect():

  1. R collect(Dodávateľ<R> dodávateľ, BiConsumer<R, ? super T> akumulátor,BiConsumer<R, R> kombinátor)
  2. <R, A> R collect(Collector<? super T, A, R> collector)

Prvá varianta má tri funkcie ako argumenty:

  • dodávateľ: vytvorí kontajner, ktorý sa bude používať na uloženie priebežných výsledkov
  • akumulátor: vypočíta konečný výsledok
  • kombinátor: kombinuje výsledky paralelných operácií s dátovými tokmi

Tieto preddefinované kolektory sú už zahrnuté v štandardnej knižnici a dajú sa ľahko importovať a používať.

Druhá varianta prijíma ako argument kolektor a vráti výsledok.

  • R: typ výsledku
  • T: typ prvkov v prúde
  • A: typ akumulátora, ktorý ukladá priebežný stav operácie zberača
  • kolektor: vykonáva redukčnú operáciu.

Pomocou tejto varianty môžu vývojári vytvárať vlastné zberače, ktoré sú špeciálne prispôsobené ich požiadavkám a poskytujú väčšiu flexibilitu a kontrolu nad procesom redukcie.

Aké sú praktické príklady použitia Java collect()?

Nižšie ilustrujeme rôzne funkcie metódy Stream.collect(). Predtým, ako sa pustíte do kolekčného rámca, mali by ste sa oboznámiť so základnými operátormi jazyka Java.

Zreťazenie zoznamu reťazcov

Pomocou Java Collect() môžeme zreťaziť zoznam reťazcov a získať tak nový reťazec:

List<String> letters = List.of("a", "b", "c", "d", "e");
// without combiner function
StringBuilder result = letters.stream().collect(StringBuilder::new, (x, y) -> x.append(y),
    (a, b) -> a.append(",").append(b));
System.out.println(result.toString());
// with combiner function
StringBuilder result1 = letters.parallelStream().collect(StringBuilder::new, (x, y) -> x.append(y),
    (a, b) -> a.append(",").append(b));
System.out.println(result1.toString());
Java

Výstup je:

abcde
a, b, c, d, e
Java

V prvom výpočte bola použitá iba jedna inštancia StringBuilder a nebola použitá žiadna kombinovacia funkcia. Preto je výsledok abcde.

V druhom výstupe funkcia kombinátora zlúčila inštancie StringBuilder a oddelila ich čiarkou.

Zbierajte prvky do zoznamu pomocou toList()

Pomocou funkcie filter() môžeme vybrať určité prvky zo zoznamu a potom pomocou toList() ich uložiť do nového zoznamu.

List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7);
List<Integer> oddNumbers = numbers.stream().filter(x -> x % 2 != 0).collect(Collectors.toList());
System.out.println(oddNumbers);
Java

V novom zozname sú len nepárne čísla:

[1, 3, 5, 7]
Java

Zbierajte prvky do súboru pomocou toSet()

Podobne môžeme vybrať prvky a vytvoriť z nich novú množinu. Prvky v množine nemusia byť usporiadané v určitom poradí.

List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7);
Set<Integer> evenNumbers = numbers.parallelStream().filter(x -> x % 2 == 0).collect(Collectors.toSet());
System.out.println(evenNumbers);
Java

Zobrazí sa tento výstup:

[2, 4, 6]
Java

Zbierajte prvky v mape pomocou toMap()

Mapu je možné použiť spolu s funkciou Java collect(), aby sa každej kľúčovej hodnote priradila hodnota.

List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7);
Map<Integer, String> mapEvenNumbers = numbers.parallelStream().filter(x -> x % 2 == 0)
    .collect(Collectors.toMap(Function.identity(), x -> String.valueOf(x)));
System.out.println(mapEvenNumbers);
Java

Vo výstupe vidíme, že každému párnemu číslu vo vstupe bola priradená hodnota, ktorá je s ním identická:

{2=2, 4=4, 6=6}
Java

Kombinujte prvky v reťazci pomocou spojenia()

Metóda joining() kombinuje prvky v prúde v poradí, v akom sa objavujú, a používa oddeľovač na oddelenie prvkov. Oddeľovač sa odovzdáva ako argument metóde joining(). Ak nie je špecifikovaný žiadny oddeľovač, joining() používa prázdny reťazec "".

jshell> String result1 = Stream.of("a", "b", "c").collect(Collectors.joining());
jshell> String result2 = Stream.of("a", "b", "c").collect(Collectors.joining(",", "{", "}"));
Java

Výsledky sú nasledovné:

result1 ==> "abc"
result2 ==> "{a,b,c}"
Java
Prejsť na hlavné menu