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 ();
Så 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.