Java 8 voogude õpetus koos koodinäidetega

Selles blogipostituses käsitleme Java 8 voogude funktsioone ja pakume palju erinevaid koodinäiteid.

Java voogud toovad Java-sse funktsionaalse programmeerimise ja neid toetatakse alates java 8-st, nii et kui teil on Java-versioon vanem, peate Java-voogude kasutamiseks täiendama Java 8-le.



Miks kasutada Java voogusid?

Mõned voogude eelised:


  • Vood muudavad teid tõhusamaks Java-programmeerijaks (näete, et väga väheste koodiridade abil saate voogude abil tegelikult üsna palju saavutada).
  • Nad kasutavad palju lambda väljendeid, mis on omamoodi ühekordsed funktsioonid.
  • ParallelStreams võimaldab suurte andmekogumite jaoks mitmekülgselt toiminguid teha väga lihtsalt.


Voolab torujuhtme

Enamasti koosneb ojaga torujuhe a

  • allikas (kust teie andmed välja voolavad)
  • järgneb null või rohkem vahepealsed toimingud
  • ja üks terminali töö

Java voogud - filtreerimine, kaardistamine, vähendamine


Allikas hakkab voogesitama elementide voogu.

Seda elementide voogu saab filtreerida, sorteerida või kaardistada või rakendada igale elemendile erinevaid muid toimingute seeriaid.

Lõpus saab seda kas koguda või vähendada või teha mõne muu terminali operatsiooni, kuid tehakse ainult üks terminali toiming.

Voo allikas

Voo allikas võivad pärineda kogudest, loenditest, komplektidest, int-de, pikkade, topeltide, stringide jne massiividest


Voooperatsioonid

Voogesitustoimingud on kas vahepealsed või terminalid:

  • Vahepealsed toimingud näiteks filter, kaart või sortimine tagastavad voo, et saaksime aheldada mitu vahepealset toimingut.
  • Terminali toimingud voogu vastu võtta ja nad võivad tagasi tulla tühjad või nad võivad anda tagasi voo välise tulemuse, näiteks vähendamise, nt. taandage üksused loendisse.

Vahetööd

  • Lubatud on null või enam vahepealset toimingut.
  • Tellimus loeb; suurte andmekogumite jaoks: kõigepealt filter siis sortige või kaardistage.
  • Väga suurte andmekogumite jaoks lubage meil ParallelStream mitme lõime lubamiseks.

Mõned vaheoperatsioonid hõlmavad järgmist:

  • anyMatch ()
  • eristatav ()
  • filter ()
  • findFirst ()
  • korterkaart ()
  • kaart ()
  • vahele jätma()
  • sorteeritud ()

Terminali toimingud

Lubatud on ainult ühe terminali hankimine.

  • forEach rakendab iga elemendi jaoks sama funktsiooni, näiteks printib iga elemendi.
  • kogu salvestab kõik elemendid kogusse, loendisse või massiivi.
  • kõik muud valikud vähendavad voogu ühe kokkuvõtte elemendiks.

Mõned näited vähendusfunktsioonidest on:


  • loenda ()
  • max ()
  • min ()
  • vähendama ()


Java voogude koodinäited

Vaatame nüüd ülaltoodud mõisteid koodinäidetes.

Tervikvoog

Esimene näide on lihtsalt täisarvu voog. Loome IntStream abil täisarvu voo klass ja selle vahemiku funktsioon, mis annab meile hulga täisarvusid.

forEach on meie terminali töö. Iga üksuse jaoks printime selle lihtsalt välja.

import java.io.IOException; import java.util.stream.IntStream; public class JavaStreams {
public static void main(String[] args) throws IOException {
IntStream

.range(1, 10)

.forEach(System.out::print);
System.out.println();
} }

Väljund:


123456789

Kogu voog koos vahelejätmisega

Teises näites kasutatakse täisarvu voogu, kuid lisasime skip() siin, nii et sel juhul jätame oma voo esimesed 5 elementi vahele.

See on ainult elementide 6–9 printimine. Üksuse printimiseks kasutame ka lihtsat lambda-väljendit

import java.io.IOException; import java.util.stream.IntStream; public class JavaStreams {
public static void main(String[] args) throws IOException {
IntStream

.range(1, 10)

.skip(5)

.forEach(x -> System.out.println(x));
System.out.println();
} }

Väljund:

6 7 8 9

Tervikvoog koos summaga

Kolmas näide, kasutame jällegi IntStream objektide voo loomiseks panime selle println() sisse lause trükirea parameetrina.


See, mida me printime, on ainult summa vahemikus 1–5 ehk 1 2 3 ja 4 prindib välja ainult nende arvude summa:

import java.io.IOException; import java.util.stream.IntStream; public class JavaStreams {
public static void main(String[] args) throws IOException {
System.out.println(
IntStream

.range(1, 5)

.sum());
System.out.println();
} }

Väljund:

10

Stream.of

Järgmine näide kasutab Stream.of funktsioon, mis on tõesti mugav, kuna saate voogesitada täisarvusid, ujukoma väärtusi või stringe või isegi objekte.

Selles näites teeme lihtsalt sirgjoonelise tähestikulise järjestuse, seejärel leiame esimese üksuse, kasutades findFirst() funktsioon. Seejärel printime lihtsalt loendi esimese üksuse välja.

import java.io.IOException; import java.util.stream.Stream; public class JavaStreams {
public static void main(String[] args) throws IOException {
Stream.of('Ava', 'Aneri', 'Alberto')

.sorted()

.findFirst()

.ifPresent(System.out::println);
} }

Väljund

Alberto

Saate massiivist voogesitada, sortida, filtreerida ja printida

Järgmises näites voogesitame massiivist. Seejärel sorteerime, filtreerime ja siis printime.

Filtreerime siin ainult üksused, mis algavad tähtedega s

Kasutame lambda väljendit, mis võtab sisse X mis on iga nimi ja siis kontrollitakse, millised algavad tähega s ja see annab need edasi.

Seejärel sorteerime need ja siis printime selle iga üksuse jaoks, mis selle sordi läbib.

import java.io.IOException; import java.util.Arrays; public class JavaStreams {
public static void main(String[] args) throws IOException {
String[] names = {'Al', 'Ankit', 'Kushal', 'Brent', 'Sarika', 'amanda', 'Hans', 'Shivika', 'Sarah'};
Arrays.stream(names)


.filter(x -> x.startsWith('S'))


.sorted()


.forEach(System.out::println);
} }

Väljund:

Sarah Sarika Shivika

Täisarvu massiivi keskmine

Vaatame nüüd, kuidas saaksime int-massiivi ruutude keskmist võtta.

Siin kasutame Arrays.stream() täisarvude voogesitamiseks ja siis hakkame kasutama map() iga üksuse iga täisarvu kaardistamiseks oma ruuduga.

import java.util.Arrays; public class JavaStreams {
public static void main(String[] args) {
Arrays.stream(new int[] {2, 4, 6, 8, 10})


.map(x -> x * x)


.average()


.ifPresent(System.out::println);
} }

Väljund:

44.0

Pange tähele, et see prinditakse täisarvu asemel topelt.

Edastage loendist, filtreerige ja printige

Selles näites voogesitame loendist, filtreerime need üksused ja seejärel printime.

Pange tähele, et map() funktsiooni, teisendame kõik nimed väiketähtedeks.

import java.util.Arrays; import java.util.List; public class JavaStreams {
public static void main(String[] args) {
List people = Arrays.asList('Al', 'Ankit', 'Brent', 'Sarika', 'amanda', 'Hans', 'Shivika', 'Sarah');
people


.stream()


.map(String::toLowerCase)


.filter(x -> x.startsWith('a'))


.forEach(System.out::println);
} }

Väljund:

al ankit amanda

Näeme, et meil on kolm nime, mis algavad a ja nad kõik on väiketähtedega.

Ridade voogesitamine tekstifailist, sortimine, filtreerimine ja printimine

Järgmises näites voogesitame read tekstifailist. Me hakkame sortima, filtreerima ja printima.

Oletame, et meil on fail nimega bands.txt allpool näidatud sisuga:

Rolling Stones Lady Gaga Jackson Browne Maroon 5 Arijit Singh Elton John John Mayer CCR Eagles Pink Aerosmith Adele Taylor Swift

Kasutame Files.lines() meie voo loomiseks, mis annab meile faili iga rea ​​jaoks stringi voo.

Kui voog on käes, sorteerime need ja filtreerime välja üksused, mis on pikemad kui 13 tähemärki, ja printime siis järelejäänud üksused.

Lõpuks peame faili sulgema, nii et teeme bands.close

import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.stream.Stream; public class JavaStreams {
public static void main(String[] args) throws IOException {
Stream bands = Files.lines(Paths.get('bands.txt'));
bands


.sorted()


.filter(x -> x.length() > 13)


.forEach(System.out::println);
bands.close();
} }

Väljund:

Jackson Browne Rolling Stones

Saame kaks ansamblit, millel on rohkem kui 13 tähemärki.

Voogedastage read tekstifailist ja salvestage loendisse

Selle näite puhul kasutame sama tekstifaili nagu eespool.

Soovime filtreerida üksused, mis sisaldavad tähti jit, kasutades x.contains() mis on lihtsalt stringi funktsioon.

Kasutades .collect() liidame kõik tähtedega jit loendisse.

Kui nimekiri on väljas, saame seejärel kasutada nuppu forEach operaator üksuste printimiseks.

import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.List; import java.util.stream.Collectors; public class JavaStreams {
public static void main(String[] args) throws IOException {
List bands2 = Files.lines(Paths.get('bands.txt'))


.filter(x -> x.contains('jit'))


.collect(Collectors.toList());
bands2.forEach(x -> System.out.println(x));
} }

Väljund:

Arijit Singh

Voogesitage read CSV-failist ja loendage

Selles näites voogesitame ridu CSV-failist ja loeme häid ridu.

Oletame, et meil on fail nimega data.txt järgmise sisuga:

A,12,3.7 B,17,2.8 C,14,1.9 D,23,2.7 E F,18,3.4

Siin pole real E andmeid, seega tahame selle oma voost välja jätta.

Järgmises koodis loeme igas reas, siis peame komades jagama massiiviks, nii et igast reast saab üksuste massiiv.

Seejärel rakendame filtri, et välja filtreerida read, millel pole kolme üksust.

import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.stream.Stream; public class JavaStreams {
public static void main(String[] args) throws IOException {
Stream rows1 = Files.lines(Paths.get('data.txt'));
int rowCount = (int)rows1


.map(x -> x.split(','))


.filter(x -> x.length == 3)


.count();
System.out.println(rowCount + ' rows.');
rows1.close();
} }

Väljund:

5 rows

Reduktsioon - summa

See näide näitab, kuidas reduktsiooni kasutada. Taandame summa. Siin on meil topeltvoog, kasutades Stream.of() funktsioon. Oleme määranud kolm duublit kolmes erinevas argumendis ja kasutame funktsiooni redutseerimine.

import java.util.stream.Stream; public class JavaStreams {
public static void main(String[] args) {
double total = Stream.of(7.3, 1.5, 4.8)


.reduce(0.0, (Double a, Double b) -> a + b);
System.out.println('Total = ' + total);
} }

Väljund:

13.600000000000001