Stream Col­lec­tors on Java 8 Stream API võimas funkt­sioon, mis võimaldab teil andmeid tõhusalt koguda ja töödelda. Siin selgitame nende struk­tuuri ja kuidas Java collect() meetodit kasutada.

Kuidas saab kasutada Java collect()-i?

Stream Collector’it saab kasutada voost nimekirja, kogumi või kaardi loomiseks. Vool on jär­jes­tikku töö­del­da­vate ele­men­tide jada. Collector’i liides pakub voo to­ru­juht­mes olevate andmete jaoks rea vä­hen­dus­ope­rat­sioone. Need on lõppo­pe­rat­sioo­nid, mis koguvad ja ühendavad va­hee­tap­pide tulemused.

Kogujaid saab kasutada voost objektide filt­ree­ri­miseks või sor­tee­ri­miseks. Samuti on võimalik koon­da­mine, näiteks numbrite sum­mee­ri­mine, stringide ühen­da­mine või ele­men­tide loen­da­mine. Lisaks on kogujatel funkt­sioo­nid, mis või­mal­da­vad voo sisu tei­sen­dada kindlaks struk­tuu­riks. Näiteks saab nimekirja tei­sen­dada kaardiks. Rüh­mi­tu­sed aitavad ka­te­go­ri­see­rida elemente teatud omaduste või tin­gi­muste alusel. Kõige olulisem on see, et voo kogujatel on eelis, et nad saavad töödelda andmeid sa­ma­aeg­selt mitme niidi abil. See võimaldab ope­rat­sioone teha palju kiiremini ja tõ­hu­sa­malt, eriti suurte and­me­mah­tude puhul.

Mis on Java collect() süntaks?

Meetod võtab ar­gu­men­dina vastu kol­lek­tori, mis kirjeldab, kuidas voo elemendid tuleks koguda ja koondada. Kollektor on liides, mis pakub erinevaid meetodeid voo ele­men­tide koon­da­miseks kindlasse vormi, näiteks nimekirja, kogumisse või kaardile.

Java Stream collect() meetodil on kaks varianti:

  1. R collect(Supplier<R> tarnija, BiCon­su­mer<R, ? super T> aku­mu­laa­tor, BiCon­su­mer<R, R> kom­bi­naa­tor)
  2. <R, A> R koguda(Koguja<? super T, A, R> koguja)

Esimesel variandil on kolm funkt­siooni ar­gu­men­ti­dena:

  • tarnija: loob va­he­tu­le­muste jaoks ka­su­ta­tava kon­tei­neri
  • aku­mu­laa­tor: arvutab lõpp­tu­le­muse
  • kom­bi­naa­tor: ühendab pa­ral­leel­sete vooo­pe­rat­sioo­nide tulemused

Need eel­mää­ra­tud kogujad on juba stan­dard­tee­gis olemas ja neid saab hõlpsasti importida ja kasutada.

Teine variant võtab ar­gu­men­dina vastu kol­lek­tori ja tagastab tulemuse.

  • R: tulemuse tüüp
  • T: voo ele­men­tide tüüp
  • A: aku­mu­laa­tori tüüp, mis salvestab koguja ope­rat­siooni va­he­pealse seisundi
  • koguja: teostab re­dukt­sioo­ni­ope­rat­siooni.

Selle variandi abil saavad arendajad luua oma va­ja­dus­tele spet­siaal­selt ko­han­da­tud kogujaid, mis pakuvad suuremat paind­lik­kust ja kontrolli vä­hen­da­mis­prot­sessi üle.

Millised on prak­ti­li­sed näited Java collect() ka­su­ta­miseks?

Allpool il­lust­ree­rime Stream.collect() meetodi erinevaid funkt­sioone. Enne kol­lekt­siooni raa­mis­tikku sü­ve­ne­mist peaksite olema juba tuttav Java põ­hi­ope­raa­to­ri­tega.

Stringide loendi ühen­da­mine

Java Collect() abil saame ühendada stringide loendi, et saada uus string:

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äljund on:

abcde
a, b, c, d, e
Java

Esimeses arvutuses kasutati ainult ühte String­Buil­deri instantsi ja kom­bi­nee­ri­mis­funkt­siooni ei olnud. Seetõttu on tulemus abcde.

Teises väljundis ühendas kom­bi­nee­ri­mis­funkt­sioon String­Buil­deri ins­tant­sid ja eraldas need komaga.

Koguge elemendid nimekirja toList() abil

Me saame kasutada funkt­siooni filter(), et valida loendi teatud elemendid, ja seejärel kasutada toList(), et need uude loendisse sal­ves­tada.

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

Uues ni­me­kir­jas on ainult paaritud numbrid:

[1, 3, 5, 7]
Java

Koguge elemendid komplekti funkt­sioo­niga toSet()

Samamoodi saame valida elemendid ja luua neist uue hulga. Hulgasse kuuluvad elemendid ei pea olema kindlas jär­je­kor­ras.

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

See kuvab väljundi:

[2, 4, 6]
Java

Koguge elemendid kaardile funkt­sioo­niga toMap()

Kaarti saab kasutada koos Java collect()-iga, et määrata igale võtmele väärtus.

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äljundis näeme, et igale sisendi paa­ris­ar­vule on omistatud sellega identne väärtus:

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

Ühendage stringi elemendid funkt­sioo­niga joining()

Meetod joining() ühendab voo elemendid nende ilmumise jär­je­kor­ras ja kasutab eraldajat ele­men­tide eral­da­miseks. Eraldaja edas­ta­takse ar­gu­men­dina meetodile joining(). Kui eraldajat ei ole määratud, kasutab joining() tühja stringi "".

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

Tulemused on järgmised:

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

2031f050ecb6acd05c8d5a15242b684b

b0935f2d0a8a22847f34c718bc1097e2

Go to Main Menu