Introduktion til Java 8 Streams

1. Oversigt

I denne artikel får vi et hurtigt kig på en af ​​de vigtigste dele af den nye funktionalitet, Java 8 havde tilføjet - Streams.

Vi forklarer, hvad streams handler om, og viser oprettelsen og de grundlæggende streamoperationer med enkle eksempler.

2. Stream API

En af de vigtigste nye funktioner i Java 8 er introduktionen af ​​stream-funktionaliteten - java.util.stream - som indeholder klasser til behandling af sekvenser af elementer.

Den centrale API-klasse er Strøm. Følgende afsnit viser, hvordan streams kan oprettes ved hjælp af de eksisterende dataleverandørkilder.

2.1. Stream Creation

Streams kan oprettes fra forskellige elementkilder, f.eks. samling eller matrix ved hjælp af strøm() og af() metoder:

Streng [] arr = ny Streng [] {"a", "b", "c"}; Stream stream = Arrays.stream (arr); stream = Stream.of ("a", "b", "c");

EN strøm() standardmetoden føjes til Kollektion interface og tillader oprettelse af en Strøm ved hjælp af enhver samling som en elementkilde:

Stream stream = list.stream (); 

2.2. Multi-threading med streams

Stream API forenkler også multithreading ved at levere parallelStream () metode, der kører operationer over strømens elementer i parallel tilstand.

Koden nedenfor gør det muligt at køre metoden lav arbejde() parallelt for hvert element i strømmen:

list.parallelStream (). forEach (element -> doWork (element));

I det følgende afsnit introducerer vi nogle af de grundlæggende Stream API-operationer.

3. Stream-operationer

Der er mange nyttige operationer, der kan udføres på en stream.

De er opdelt i mellemliggende operationer (Vend tilbage Strøm) og terminaloperationer (returner et resultat af bestemt type). Mellemliggende operationer muliggør sammenkædning.

Det er også værd at bemærke, at operationer på streams ikke ændrer kilden.

Her er et hurtigt eksempel:

lang optælling = liste.strøm (). særskilt (). antal ();

tydelig () metode repræsenterer en mellemliggende operation, som skaber en ny strøm af unikke elementer i den tidligere strøm. Og tælle() metoden er en terminaloperation, som returnerer streams størrelse.

3.1. Itererende

Stream API hjælper med at erstatte til, for hverog mens sløjfer. Det giver mulighed for at koncentrere sig om operationens logik, men ikke om iteration over rækkefølgen af ​​elementer. For eksempel:

for (String string: list) {if (string.contains ("a")) {return true; }}

Denne kode kan ændres kun med en linje Java 8-kode:

boolsk isExist = list.stream (). anyMatch (element -> element.contains ("a"));

3.2. Filtrering

Det filter() metode giver os mulighed for at vælge en strøm af elementer, der tilfredsstiller et prædikat.

Overvej f.eks. Følgende liste:

ArrayList liste = ny ArrayList (); list.add ("One"); list.add ("OneAndOnly"); list.add ("Derek"); list.add ("Skift"); list.add ("fabrik"); list.add ("justBefore"); list.add ("Italien"); list.add ("Italien"); list.add ("torsdag"); list.add (""); list.add ("");

Den følgende kode opretter en Strøm af Liste, finder alle elementer i denne strøm, der indeholder char “d”, og opretter en ny stream, der kun indeholder de filtrerede elementer:

Stream stream = list.stream (). Filter (element -> element.contains ("d"));

3.3. Kortlægning

At konvertere elementer i en Strøm ved at anvende en særlig funktion på dem og samle disse nye elementer i en Strøm, kan vi bruge kort() metode:

Liste uris = ny ArrayList (); uris.add ("C: \ My.txt"); Stream stream = uris.stream (). Kort (uri -> Paths.get (uri));

Så ovenstående kode konverterer Strøm til Strøm ved at anvende et specifikt lambda-udtryk på hvert element i initialen Strøm.

Hvis du har en strøm, hvor hvert element indeholder sin egen række af elementer, og du vil oprette en strøm af disse indre elementer, skal du bruge flatMap () metode:

Listeoplysninger = ny ArrayList (); details.add (ny detalje ()); Stream stream = details.stream (). FlatMap (detail -> detail.getParts (). Stream ());

I dette eksempel har vi en liste over elementelementer af typen Detalje. Det Detalje klasse indeholder et felt DELE, som er en Liste. Ved hjælp af flatMap () metode, hvert element fra felt DELE ekstraheres og føjes til den nye resulterende strøm. Derefter begyndelsen Strøm vil gå tabt.

3.4. Matchende

Stream API giver et praktisk sæt instrumenter til at validere elementer i en sekvens ifølge et eller andet predikat. For at gøre dette kan en af ​​følgende metoder bruges: anyMatch (), allMatch (), noneMatch (). Deres navne er selvforklarende. Det er terminaloperationer, der returnerer a boolsk:

boolsk isValid = list.stream (). anyMatch (element -> element.contains ("h")); // sand boolsk isValidOne = list.stream (). allMatch (element -> element.contains ("h")); // falsk boolsk isValidTwo = list.stream (). noneMatch (element -> element.contains ("h")); // falsk

For tomme vandløb er allMatch () metode med et givet predikat vender tilbage rigtigt:

Stream.empty (). AllMatch (Objekter :: nonNull); // rigtigt

Dette er en fornuftig standard, da vi ikke kan finde noget element, der ikke opfylder prædikatet.

Tilsvarende er anyMatch () metoden vender altid tilbage falsk til tomme vandløb:

Stream.empty (). AnyMatch (Objekter :: nonNull); // falsk

Igen er dette rimeligt, da vi ikke kan finde et element, der opfylder denne betingelse.

3.5. Reduktion

Stream API giver mulighed for at reducere en sekvens af elementer til en værdi i henhold til en bestemt funktion ved hjælp af reducere() metode af typen Strøm. Denne metode tager to parametre: første startværdi, anden - akkumulatorfunktion.

Forestil dig, at du har en Liste og du vil have en sum af alle disse elementer og nogle initialer Heltal (i dette eksempel 23). Så du kan køre følgende kode, og resultatet bliver 26 (23 + 1 + 1 + 1).

Liste heltal = Arrays.asList (1, 1, 1); Heltal reduceret = heltal.stream (). Reducere (23, (a, b) -> a + b);

3.6. Indsamling

Reduktionen kan også tilvejebringes af indsamle() metode af typen Strøm. Denne handling er meget praktisk i tilfælde af konvertering af en stream til en Kollektion eller a Kort og repræsenterer en strøm i form af en enkelt streng. Der er en hjælpeklasse Samlere som giver en løsning til næsten alle typiske indsamlingsoperationer. For nogle, ikke trivielle opgaver, en brugerdefineret Samler kan oprettes.

Liste resultatListe = liste.strøm (). Kort (element -> element.toUpperCase ()). Indsamle (Collectors.toList ());

Denne kode bruger terminalen indsamle() operation for at reducere en Strøm til Liste.

4 konklusioner

I denne artikel berørte vi kort Java-streams - bestemt en af ​​de mest interessante Java 8-funktioner.

Der er mange mere avancerede eksempler på brug af Streams; Målet med denne opskrivning var kun at give en hurtig og praktisk introduktion til, hvad du kan begynde at gøre med funktionaliteten og som udgangspunkt for udforskning og videre læring.

Kildekoden, der ledsager artiklen, er tilgængelig på GitHub.