Srauto su­rin­kė­jai yra galinga Java 8 srauto API funkcija, lei­džian­ti efek­ty­viai rinkti ir apdoroti duomenis. Čia pa­aiš­kin­si­me jų struktūrą ir kaip galima naudoti Java collect() metodą.

Kaip galima naudoti Java collect()?

Srauto ko­lek­to­rius gali būti nau­do­ja­mas sąrašui, rinkiniui ar že­mė­la­piui iš srauto sukurti. Srautas yra elementų seka, kurie ap­do­ro­ja­mi vienas po kito. Ko­lek­to­riaus sąsaja teikia srauto vamzdyne esančių duomenų re­duk­ci­jos operacijų rinkinį. Tai yra galutinės ope­ra­ci­jos, kurios renka ir sujungia tarpinio etapo re­zul­ta­tus.

Ko­lek­to­riai gali būti naudojami objektams iš srauto filtruoti ar rūšiuoti. Taip pat galima atlikti ag­re­ga­ci­ją, pa­vyz­džiui, sudėti skaičius, sujungti eilutes ar su­skai­čiuo­ti elementus. Be to, ko­lek­to­riai turi funkcijas, kurios gali trans­for­muo­ti srauto turinį į tam tikrą struktūrą. Pa­vyz­džiui, galite trans­for­muo­ti sąrašą į žemėlapį. Gru­pa­vi­mas padeda ka­te­go­ri­zuo­ti elementus pagal tam tikras savybes ar sąlygas. Svar­biau­sia, srauto ko­lek­to­riai turi pranašumą, kad jie gali apdoroti duomenis tuo pačiu metu naudodami kelis sriegius. Tai leidžia ope­ra­ci­jas atlikti daug greičiau ir efek­ty­viau, ypač kai duomenų kiekis yra didelis.

Kokia yra Java collect() sintaksė?

Šis metodas kaip argumentą priima ko­lek­to­rių, kuris apibūdina, kaip srauto elementai turėtų būti renkami ir ag­re­guo­ja­mi. Ko­lek­to­rius yra sąsaja, kuri teikia įvairius metodus srauto ele­men­tams agreguoti į tam tikrą formą, pa­vyz­džiui, į sąrašą, rinkinį ar žemėlapį.

Yra du Java Stream collect() metodo variantai:

  1. R collect(Supplier<R> tiekėjas, Bi­Con­su­mer<R, ? super T> kaupiklis, Bi­Con­su­mer<R, R> jungiklis)
  2. <R, A> R rinkti(Rinkėjas<? super T, A, R> rinkėjas)

Pirmasis variantas turi tris funkcijas kaip ar­gu­men­tus:

  • tiekėjas: sukuria kon­t­ei­ne­rį, kuris bus nau­do­ja­mas tar­pi­niams re­zul­ta­tams
  • aku­mu­lia­to­rius: ap­skai­čiuo­ja galutinį rezultatą
  • kom­bi­na­to­rius: sujungia ly­gia­gre­čių srautų operacijų re­zul­ta­tus

Šie iš anksto apibrėžti ko­lek­to­riai jau yra įtraukti į stan­dar­ti­nę bi­b­lio­te­ką ir juos galima lengvai im­por­tuo­ti bei naudoti.

Antrasis variantas priima ko­lek­to­rių kaip argumentą ir grąžina rezultatą.

  • R: rezultato tipas
  • T: srauto elementų tipas
  • A: aku­mu­lia­to­riaus, kuriame saugoma tarpinė ko­lek­to­riaus ope­ra­ci­jos būsena, tipas
  • ko­lek­to­rius: vykdo re­duk­ci­jos operaciją.

Naudodami šį variantą, kūrėjai gali kurti in­di­vi­dua­li­zuo­tus ko­lek­to­rius, kurie yra spe­cia­liai pri­tai­ky­ti jų rei­ka­la­vi­mams ir suteikia didesnį lankstumą bei kontrolę mažinimo procese.

Kokie yra prak­ti­niai Java collect() naudojimo pa­vyz­džiai?

Toliau pa­tei­kia­me Stream.collect() metodo įvairias funkcijas. Prieš pradėdami dirbti su kolekcijų struktūra, tu­rė­tu­mė­te būti su­si­pa­ži­nę su pag­rin­di­niais Java ope­ra­to­riais.

Sujungti stygų sąrašą

Naudodami Java Collect(), galime sujungti stygų sąrašą, kad gautume naują stygą:

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

Re­zul­ta­tas yra:

abcde
a, b, c, d, e
Java

Pirmajame skai­čia­vi­me buvo nau­do­ja­mas tik vienas String­Buil­der eg­zemp­lio­rius ir nebuvo jokios jungimo funkcijos. Todėl re­zul­ta­tas yra abcde.

Antrajame išvesties rezultate sujungimo funkcija sujungė String­Buil­der eg­zemp­lio­rius ir atskyrė juos kableliu.

Surinkite elementus į sąrašą naudodami toList()

Mes galime naudoti filter() funkciją, kad at­rink­tu­me tam tikrus sąrašo elementus, o tada naudoti toList(), kad juos iš­sau­go­tu­me naujame sąraše.

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

Naujajame sąraše yra tik ne­ly­gi­niai skaičiai:

[1, 3, 5, 7]
Java

Surinkite elementus į rinkinį naudodami toSet()

Panašiai, mes galime pa­si­rink­ti elementus ir iš jų sukurti naują rinkinį. Rinkinio elementai neturi būti išdėstyti tam tikra tvarka.

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

Tai rodo išvestį:

[2, 4, 6]
Java

Rinkite elementus že­mė­la­py­je naudodami toMap()

Žemėlapį galima naudoti kartu su Java collect(), kad kiek­vie­nam raktui būtų priskirta reikšmė.

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

Rezultate matome, kad kiek­vie­nam įvesties poriniam skaičiui buvo priskirta jam identiška reikšmė:

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

Sujunkite elementus į eilutę naudodami jungimo funkciją ()

joining() metodas sujungia elementus sraute ta tvarka, kuria jie pasirodo, ir naudoja at­sky­rik­lį ele­men­tams atskirti. At­sky­rik­lis per­duo­da­mas kaip ar­gu­men­tas joining(). Jei at­sky­rik­lis ne­nu­ro­dy­tas, joining() naudoja tuščią eilutę "".

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

Re­zul­ta­tai yra tokie:

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

2031f050ecb6acd05c8d5a15242b684b

0cacb08f2ba4d3f69e4e6722d466a801

Go to Main Menu