Zbi­ral­ni­ki tokov so močna funk­ci­o­nal­nost v API-ju Java 8 Stream, ki omogoča učin­ko­vi­to zbiranje in obdelavo podatkov. Tukaj bomo pojasnili njihovo strukturo in kako se lahko uporablja metoda Java collect().

Kako se lahko uporabi Java collect()?

Zbiralnik toka se lahko uporabi za ustvar­ja­nje seznama, niza ali ze­mlje­vi­da iz toka. Tok je zaporedje elementov, ki se ob­de­lu­je­jo eden za drugim. Vmesnik zbi­ral­ni­ka za­go­ta­vlja niz operacij zmanj­še­va­nja za podatke v tokovnem vodilu. To so ter­mi­nal­ne operacije, ki zbirajo in zdru­žu­je­jo rezultate vmesnih korakov.

Zbi­ral­ni­ki se lahko upo­ra­blja­jo za fil­tri­ra­nje ali raz­vr­šča­nje objektov iz toka. Mogoče je tudi zdru­že­va­nje, na primer se­šte­va­nje številk, zdru­že­va­nje nizov ali štetje elementov. Poleg tega imajo zbi­ral­ni­ki funkcije, ki lahko pre­tvo­ri­jo vsebino toka v določeno strukturo. Seznam lahko na primer pre­tvo­ri­te v zemljevid. Skupine pomagajo ka­te­go­ri­zi­ra­ti elemente z do­lo­če­ni­mi la­stnost­mi ali pogoji. Naj­po­memb­nej­ša prednost zbi­ral­ni­kov tokov je, da lahko ob­de­lu­je­jo podatke hkrati z več nitmi. To omogoča veliko hitrejše in učin­ko­vi­tej­še izvajanje operacij, zlasti pri velikih količinah podatkov.

Kakšna je sintaksa za Java collect()?

Metoda sprejme kot argument zbiralnik, ki opisuje, kako je treba zbrati in združiti elemente toka. Zbiralnik je vmesnik, ki ponuja različne metode za zdru­že­va­nje elementov toka v določeno obliko, na primer v seznam, niz ali zemljevid.

Obstajata dve različici metode Java Stream collect():

  1. R zbira(do­ba­vi­telj<R> do­ba­vi­telj, Bi­Con­su­mer<R, ? super T> aku­mu­la­tor, Bi­Con­su­mer<R, R> kom­bi­na­tor)
  2. <R, A> R zbiraj(Zbiralnik<? super T, A, R> zbiralnik)

Prva različica ima tri funkcije kot argumente:

  • do­ba­vi­telj: ustvari posodo, ki se bo upo­ra­blja­la za vmesne rezultate
  • aku­mu­la­tor: izračuna končni rezultat
  • kom­bi­na­tor: združi rezultate vzpo­re­dnih operacij toka

Ti vnaprej določeni zbi­ral­ni­ki so že vključeni v stan­dar­dno knjižnico in jih je mogoče enostavno uvoziti in uporabiti.

Druga različica sprejme zbiralnik kot argument in vrne rezultat.

  • R: vrsta rezultata
  • T: vrsta elementov v toku
  • A: vrsta aku­mu­la­tor­ja, ki shranjuje vmesno stanje delovanja zbi­ral­ni­ka
  • kolektor: izvaja operacijo redukcije.

Z uporabo te variante lahko raz­vi­jal­ci ustvarijo pri­la­go­je­ne zbiralce, ki so posebej pri­la­go­je­ni njihovim zahtevam in za­go­ta­vlja­jo večjo prožnost in nadzor nad procesom zmanj­še­va­nja.

Kakšni so praktični primeri uporabe Java collect()?

Spodaj pri­ka­zu­je­mo različne funkcije metode Stream.collect(). Preden se lotite okvira zbirke, se morate seznaniti z osnovnimi ope­ra­ci­ja­mi Java.

Združi seznam nizov

Z Java Collect() lahko združimo seznam nizov, da dobimo nov niz:

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

Izhod je:

abcde
a, b, c, d, e
Java

V prvem izračunu je bila upo­ra­blje­na samo ena instanca Strin­gBu­il­der in ni bilo funkcije za zdru­že­va­nje. Zato je rezultat abcde.

V drugem izhodu je funkcija zdru­že­val­ni­ka združila instance Strin­gBu­il­der in jih ločila z vejico.

Zberite elemente v seznamu s toList()

Z uporabo funkcije filter() lahko izberemo določene elemente seznama in jih nato s funkcijo toList() shranimo v nov seznam.

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

Na novem seznamu so samo lihe številke:

[1, 3, 5, 7]
Java

Zberite elemente v nizu s toSet()

Podobno lahko izberemo elemente in iz njih ustvarimo novo množico. Elementi v množici niso nujno raz­vr­šče­ni v določenem vrstnem redu.

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

To prikaže izhod:

[2, 4, 6]
Java

Zberite elemente v ze­mlje­vi­du s toMap()

Zemljevid se lahko uporabi skupaj z Java collect(), da se vsakemu ključu dodeli vrednost.

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

V izhodu lahko vidimo, da je vsaki sodej številki v vhodu dodeljena vrednost, ki je enaka tej številki:

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

Združite elemente v niz z metodo joining()

Metoda joining() združuje elemente v toku v vrstnem redu, v katerem se po­ja­vlja­jo, in uporablja ločilo za ločevanje elementov. Ločilo se prenese kot argument v joining(). Če ločilo ni določeno, joining() uporabi prazen niz "".

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

Rezultati so:

result1 ==> "abc"
result2 ==> "{a,b,c}"
Java

2031f050ecb6acd05c8d5a15242b684b

b0935f2d0a8a22847f34c718bc1097e2

Go to Main Menu