En ström i Java är en sekvens av element på vilka sekventiella eller parallella operationer kan utföras.
Det kan finnas ett ”n” antal mellanoperationer och till sist en terminaloperation, varefter resultatet returneras.
Innehållsförteckning
Vad är en Stream?
Strömmar kan hanteras av Stream API, som introducerades i Java 8.
Föreställ dig Stream som en tillverkningspipeline där vissa varor måste tillverkas, sorteras och sedan packas för transport. I Java är dessa varor föremål eller samlingar av föremål, operationerna är tillverkning, sortering och packning, och pipelinen är strömmen.
Komponenterna i en ström är:
- En första ingång
- Mellanliggande operationer
- Terminaldrift
- Slutresultat
Låt oss utforska några funktioner i en ström i Java:
- Stream är inte en datastruktur i minnet; snarare är det en sekvens av arrayer, objekt eller samlingar av objekt som manövreras med vissa metoder.
- Strömmar är deklarativa till sin natur, dvs du anger vad som ska göras men inte hur det ska göras.
- De kan endast konsumeras en gång eftersom de inte förvaras någonstans.
- Stream ändrar inte den ursprungliga datastrukturen; den härleder bara en ny struktur från den.
- Den returnerar slutresultatet från den slutliga metoden i pipelinen.
Stream API vs. samlingsbearbetning
En samling är en datastruktur i minnet som lagrar och bearbetar data. Samlingar tillhandahåller datastrukturer som Set, Map, List, etc., för att lagra data. Å andra sidan är en ström ett sätt att effektivt överföra data efter att ha bearbetat det genom en pipeline.
Här är ett exempel på en ArrayList-samling:
import java.util.ArrayList; public class Main { public static void main(String[] args) { ArrayList list = new ArrayList(); list.add(0, 3); System.out.println(list); } } Output: [3]
Som du kan se i exemplet ovan kan du skapa en ArrayList-samling, lagra data i den och sedan arbeta på den datan med olika metoder.
Med hjälp av en ström kan du arbeta på en befintlig datastruktur och returnera ett nytt ändrat värde. Nedan är ett exempel på hur man skapar en ArrayList-samling och filtrerar den med en ström.
import java.util.ArrayList; import java.util.stream.Stream; public class Main { public static void main(String[] args) { ArrayList<Integer> list = new ArrayList(); for (int i = 0; i < 20; i++) { list.add(i+1); } System.out.println(list); Stream<Integer> filtered = list.stream().filter(num -> num > 10); filtered.forEach(num -> System.out.println(num + " ")); } } #Output [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] 11 12 13 14 15 16 17 18 19 20
I exemplet ovan skapas en ström med den befintliga listan och listan upprepas för att filtrera värden större än 10. Observera att strömmen inte lagrar någonting, listan upprepas bara och resultatet skrivs ut. Om du försöker skriva ut strömmen får du en referens till strömmen istället för värden.
Arbetar med Java Stream API
Java Stream API tar in en källsamling av element eller en sekvens av element och utför sedan operationer på dem för att få ett slutresultat. En ström är bara en rörledning genom vilken en sekvens av element passerar och omvandlas på något sätt.
En ström kan skapas från olika källor, inklusive:
- En samling som en lista eller uppsättning.
- En uppsättning.
- Från filer och deras sökvägar med hjälp av en buffert.
Det finns två typer av operationer som utförs i en ström:-
- Mellanliggande verksamhet
- Terminaldrift
Mellanliggande kontra terminaldrift
Varje mellanoperation returnerar en ny ström internt som transformerar indata med den angivna metoden. Ingenting korsas faktiskt; Istället förs den vidare till nästa ström. Det är först vid terminaloperationen som strömmen genomkorsas för att få önskat resultat.
Du har till exempel en lista med 10 nummer som du vill filtrera bort och sedan mappa till något. Inte alla element i listan kommer att passeras omedelbart för att få det filtrerade resultatet och mappa det till något annat. Istället kommer enskilda element att kontrolleras, och om de uppfyller villkoret, mappas de. Nya strömmar för varje element.
Kartoperationen kommer att utföras på enskilda objekt som uppfyller filtret och inte hela listan. Och vid tidpunkten för terminaloperationen korsas de och kombineras till ett enda resultat.
Efter att ha utfört terminaloperationen förbrukas strömmen och kan inte längre användas ytterligare. Du måste skapa en ny ström för att utföra samma operationer igen.
Källa: The Bored Dev
Med en förståelse på ytan av hur strömmar fungerar, låt oss gå in i implementeringsdetaljerna för strömmar i Java.
#1. En tom ström
Skapa en tom ström genom att använda den tomma metoden i Stream API.
import java.util.stream.Stream; public class Main { public static void main(String[] args) { Stream emptyStream = Stream.empty(); System.out.println(emptyStream.count()); } } Output: 0
Här, om du skriver ut antalet element i denna ström, får du 0 som utdata eftersom det är en tom ström utan element. Tomma strömmar är till stor hjälp för att undvika undantag för nollpekare.
#2. Streama från samlingar
Samlingar som Lists och Set visar en stream()-metod som låter dig skapa en stream från en samling. Den skapade strömmen kan sedan korsas för att få slutresultatet.
ArrayList<Integer> list = new ArrayList(); for (int i = 0; i < 20; i++) { list.add(i+1); } System.out.println(list); Stream<Integer> filtered = list.stream().filter(num -> num > 10); filtered.forEach(num -> System.out.println(num + " ")); #Output [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20] 11 12 13 14 15 16 17 18 19 20
#3. Streama från Arrays
Metoden Arrays.stream() används för att skapa en ström från en array.
import java.util.Arrays; public class Main { public static void main(String[] args) { String[] stringArray = new String[]{"this", "is", "adminvista.com"}; Arrays.stream(stringArray).forEach(item -> System.out.print(item + " ")); } } #Output this is adminvista.com
Du kan också ange start- och slutindex för elementen att skapa en ström av. Startindexet är inklusive, medan slutindexet är exklusivt.
String[] stringArray = new String[]{"this", "is", "adminvista.com"}; Arrays.stream(stringArray, 1, 3).forEach(item -> System.out.print(item + " ")); Output: is adminvista.com
#4. Hitta min- och maxtal med Streams
Att komma åt det maximala och lägsta antalet för en samling eller en array kan göras genom att använda komparatorer i Java. Metoderna min() och max() accepterar en komparator och returnerar ett Optional-objekt.
Ett valfritt objekt är ett containerobjekt som kan innehålla ett icke-nullvärde eller inte. Om den innehåller ett icke-nullvärde, returneras värdet genom att anropa get()-metoden på det.
import java.util.Arrays; import java.util.Optional; public class MinMax { public static void main(String[] args) { Integer[] numbers = new Integer[]{21, 82, 41, 9, 62, 3, 11}; Optional<Integer> maxValue = Arrays.stream(numbers).max(Integer::compare); System.out.println(maxValue.get()); Optional<Integer> minValue = Arrays.stream(numbers).min(Integer::compare); System.out.println(minValue.get()); } } #Output 82 3
Lärresurser
Nu när du har en grundläggande förståelse för strömmar i Java, här är 5 resurser för dig att bli väl bevandrad i Java 8:
#1. Java 8 i aktion
Den här boken är en guide som visar upp nya funktioner i Java 8, inklusive streams, lambdas och programmering av funktionell stil. Frågesporter och kunskapskontrollfrågor är också en del av boken, som hjälper dig att återställa det du lärt dig.
Du kan få den här boken i pocketformat såväl som i ljudboksformat på Amazon.
#2. Java 8 Lambdas: Funktionell programmering för massorna
Den här boken är speciellt utformad för att lära grundläggande Java SE-utvecklare hur tillägget av Lambda-uttryck påverkar Java-språket. Den innehåller flytande förklaringar, kodövningar och exempel för att du ska kunna bemästra Java 8 lambda-uttryck.
Den finns i pocketformat och Kindle-utgåvan på Amazon.
#3. Java SE 8 för den riktigt otåliga
Om du är en erfaren Java SE-utvecklare, kommer den här boken att guida dig genom förbättringarna som gjorts i Java SE 8, stream-API:et, tillägget av lambda-uttryck, förbättringar av samtidig programmering i Java och vissa Java 7-funktioner som de flesta människor har. vet inte om.
Den är endast tillgänglig i pocketformat på Amazon.
#4. Lär dig Java funktionell programmering med Lambdas & Streams
Denna kurs av Udemy utforskar grunderna för funktionell programmering i Java 8 och 9. Lambdauttryck, metodreferenser, strömmar och funktionella gränssnitt är begreppen som denna kurs fokuserar på.
Den innehåller också ett gäng Java-pussel och övningar relaterade till funktionell programmering.
#5. Java klassbibliotek
Java Class Library är en del av Core Java Specialization som erbjuds av Coursera. Den kommer att lära dig hur man skriver typsäker kod med Java Generics, förstår klassbiblioteket som består av över 4000 klasser, hur man arbetar med filer och hanterar runtime-fel. Det finns dock några förutsättningar för att ta denna kurs:
- Introduktion till Java
- Introduktion till objektorienterad programmering med Java
- Objektorienterade hierarkier i Java
Slutord
Java Stream API och införandet av Lambda-funktioner i Java 8 förenklade och förbättrade många saker i Java, såsom parallell iteration, funktionella gränssnitt, mindre kod, etc.
Strömmar har dock vissa begränsningar; deras största begränsning är att de bara kan konsumeras en gång. Om du är en Java-utvecklare kan resurserna som nämns ovan hjälpa dig att förstå dessa ämnen i mycket mer detalj, så se till att kolla in dem.
Du kanske också vill veta om undantagshantering i Java.