Stream Col­lec­tors ir jaudīga funkcija Java 8 Stream API, kas ļauj efektīvi vākt un apstrādāt datus. Šeit mēs iz­skaid­ro­sim to struktūru un to, kā var izmantot Java collect() metodi.

Kā var izmantot Java collect()?

Plūsmas kolektoru var izmantot, lai no plūsmas izveidotu sarakstu, kopu vai karti. Plūsma ir elementu secība, kas tiek ap­strā­dā­ti viens pēc otra. Kolektora saskarne nodrošina virkni re­duk­ci­jas operāciju datiem plūsmas cau­ruļ­va­dā. Tās ir galīgās ope­rā­ci­jas, kas apkopo un apvieno starppos­mu re­zul­tā­tus.

Kolektori var tikt izmantoti, lai filtrētu vai šķirotu objektus no plūsmas. Ir iespējama arī ag­re­gā­ci­ja, piemēram, skaitļu summēšana, virkņu ap­vie­no­ša­na vai elementu skai­tī­ša­na. Turklāt ko­lek­to­riem ir funkcijas, kas var pārveidot plūsmas saturu konkrētā struktūrā. Piemēram, jūs varat pārveidot sarakstu kartē. Grupēšana palīdz ka­te­go­ri­zēt elementus ar noteiktām īpašībām vai no­sa­cī­ju­miem. Vis­no­zī­mī­gā­kā straumju kolektoru priekš­ro­cī­ba ir tā, ka tie var apstrādāt datus vien­lai­kus, iz­man­to­jot vairākus pa­ve­die­nus. Tas ļauj ope­rā­ci­jas veikt daudz ātrāk un efektīvāk, īpaši ar lieliem datu apjomiem.

Kāda ir Java collect() sintakse?

Metode kā argumentu pieņem Collector, kas apraksta, kā straumes elementi jāvāc un jāapvieno. Collector ir saskarne, kas nodrošina dažādas metodes, lai apvienotu straumes elementus konkrētā formā, piemēram, sarakstā, kopā vai kartē.

Ir divi Java Stream collect() metodes varianti:

  1. R collect(Supplier<R> pie­gā­dā­tājs, Bi­Con­su­mer<R, ? super T> aku­mu­la­tors, Bi­Con­su­mer<R, R> kom­bi­na­tors)
  2. <R, A> R collect(Collector<? super T, A, R> collector)

Pirmajam variantam ir trīs funkcijas kā argumenti:

  • pie­gā­dā­tājs: izveido kon­tei­ne­ru, kas tiks izmantots starppos­ma re­zul­tā­tiem
  • aku­mu­la­tors: aprēķina galīgo rezultātu
  • ap­vie­no­tājs: apvieno paralēlo plūsmu operāciju re­zul­tā­tus

Šie iepriekš definētie kolektori jau ir iekļauti standarta bib­lio­tē­kā un tos var viegli importēt un izmantot.

Otrais variants pieņem Collector kā argumentu un atgriež rezultātu.

  • R: rezultāta veids
  • T: plūsmas elementu tips
  • A: aku­mu­la­to­ra tips, kas uzglabā kolektora darbības starppos­ma stāvokli
  • kolektors: veic re­duk­ci­jas darbību.

Iz­man­to­jot šo variantu, iz­strā­dā­tā­ji var izveidot pie­lā­go­tus ko­lek­to­rus, kas ir īpaši pielāgoti viņu prasībām un nodrošina lielāku elastību un kontroli pār sa­ma­zi­nā­ša­nas procesu.

Kādi ir praktiski piemēri Java collect() iz­man­to­ša­nai?

Zemāk mēs ilus­trē­jam dažādas Stream.collect() metodes funkcijas. Pirms sākt izmantot kolekciju struktūru, jums jau jābūt pa­zīs­ta­miem ar pamata Java ope­ra­to­riem.

Savienot virkni stingu

Iz­man­to­jot Java Collect(), mēs varam savienot virkni stingu, lai iegūtu jaunu stingu:

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

Rezultāts ir:

abcde
a, b, c, d, e
Java

Pirmajā aprēķinā tika izmantots tikai viens StringBuil­der instances un nebija kom­bi­na­to­ra funkcijas. Tāpēc rezultāts ir abcde.

Otrajā izvades rezultātā kom­bi­na­to­ra funkcija apvienoja StringBuil­der instancēm un atdalīja tās ar komatu.

Vāc elementus sarakstā ar toList()

Mēs varam izmantot funkciju filter(), lai atlasītu noteiktus saraksta elementus, un pēc tam izmantot toList(), lai tos saglabātu jaunā sarakstā.

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

Jaunajā sarakstā ir tikai nepāra skaitļi:

[1, 3, 5, 7]
Java

Vāc elementus kopā ar toSet()

Tāpat mēs varam atlasīt elementus un no tiem izveidot jaunu kopu. Ele­men­tiem kopā nav jābūt sa­kār­to­tiem noteiktā secībā.

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

Tad tiek parādīts šāds izvades rezultāts:

[2, 4, 6]
Java

Vāc elementus kartē ar toMap()

Karti var izmantot kopā ar Java collect(), lai katrai atslēgai piešķirtu vērtību.

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

Rezultātā redzam, ka katram ieejas pāra skaitlim ir piešķirta identiska vērtība:

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

Ap­vie­no­jiet elementus virknē ar pie­vie­no­ša­nu()

joining() metode apvieno elementus plūsmā tādā secībā, kādā tie parādās, un izmanto at­da­lī­tā­ju, lai atdalītu elementus. At­da­lī­tājs tiek nodots kā arguments joining(). Ja at­da­lī­tājs nav norādīts, joining() izmanto tukšo virkni "".

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

Rezultāti ir šādi:

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

2031f050ecb6acd05c8d5a15242b684b

b0935f2d0a8a22847f34c718bc1097e2

ead402b19b99bbd5d2481102796808ff

Go to Main Menu