Principer
Principerna för att arbeta med Stream API bygger på centrala koncept inom funktionell programmering och lat utvärdering. Här följer en översikt av de viktigaste principerna för Stream API.
Lat utvärdering
En av de grundläggande principerna för Stream API är lat utvärdering.
Detta innebär att intermediära operationer såsom filter() eller map() inte utförs omedelbart. De bildar istället en kedja av åtgärder som endast exekveras när en terminal operation, såsom collect() eller forEach(), anropas.
Main.java
12345678910111213package com.example; import java.util.List; public class Main { public static void main(String[] args) { List<String> names = List.of("Alice", "Bob", "Charlie"); long count = names.stream() .filter(name -> name.startsWith("A")) // Forming the operation .count(); // Triggering execution System.out.println(count); // Output: 1 } }
Denna kod skapar en ström från en lista av strängar, filtrerar elementen för att behålla endast de som börjar med bokstaven A, och räknar hur många som uppfyller villkoret. Resultatet (1) skrivs ut eftersom endast Alice uppfyller villkoret.
Funktionell programmeringsstil
Stream API använder lambdauttryck och funktionella gränssnitt för databearbetning. Istället för det imperativa tillvägagångssättet med loopar beskrivs vad som ska göras med data:
Main.java
1234567891011121314package com.example; import java.util.List; public class Main { public static void main(String[] args) { List<String> fruits = List.of("apple", "banana", "cherry", "apricot", "blueberry"); List<String> result = fruits.stream() .map(String::toUpperCase) // Convert all strings to uppercase .skip(3) .toList(); // Collect the result into a new list System.out.println(result); } }
Denna kod skapar en ström från en lista av frukter, konverterar strängarna till versaler med hjälp av map(), och hoppar över de tre första elementen med skip(). Resultatet samlas i en ny lista och skrivs ut, med start från det fjärde elementet.
Omutbarhet av data
Stream API ändrar inte ursprungsdata. Alla operationer skapar en ny ström eller returnerar ett resultat utan att ändra samlingen eller arrayen. Detta ökar datasäkerheten och förhindrar oväntade bieffekter.
Main.java
12345678910111213package com.example; import java.util.List; public class Main { public static void main(String[] args) { List<String> names = List.of("Alice", "Bob", "Charlie"); List<String> updateNames = names.stream() .filter(name -> name.startsWith("A")) .toList(); System.out.println(names); // Output: [Alice, Bob, Charlie] } }
Stream API filtrerar list names för att skapa en ny stream, updateNames, som endast innehåller element som börjar med bokstaven A. Dock förblir original list names oförändrad, eftersom Stream API inte modifierar data direkt, vilket säkerställer datasäkerhet och förhindrar bieffekter.
Strömmar kan endast konsumeras en gång
En stream kan användas endast en gång. Efter att en terminal operation har utförts blir stream otillgänglig för vidare bearbetning.
Main.java
123456789101112package com.example; import java.util.List; import java.util.stream.Stream; public class Main { public static void main(String[] args) { Stream<String> stream = List.of("Alice", "Bob").stream(); stream.forEach(System.out::println); stream.forEach(System.out::println); // Error: Stream has already been used } }
Här skapas en stream från en lista av strängar och varje element skrivs ut till konsolen. Efter att streamen har använts första gången kan den inte återanvändas, vilket leder till ett fel om du försöker anropa forEach() igen.
Parallell bearbetning
Stream API stöder parallella streams, vilket möjliggör snabbare databearbetning på flerkärniga system. Detta behandlas mer ingående här
Main.java
1234567891011package com.example; import java.util.List; public class Main { public static void main(String[] args) { List<Integer> numbers = List.of(1, 2, 3, 4, 5); numbers.parallelStream() .forEach(System.out::println); // Elements are processed in parallel } }
Denna kod skapar en parallell ström från en lista med tal och skriver ut varje element till konsolen. Genom att använda parallelStream() möjliggörs parallell bearbetning av listelementen, vilket kan snabba upp exekveringen vid hantering av stora datamängder.
Kodrenhet och läsbarhet
Att använda Stream API gör koden mer deklarativ. Istället för att beskriva hur en uppgift ska utföras (som att använda loopar), beskriver du vad som faktiskt behöver göras. Detta förbättrar läsbarheten och förenklar kodunderhåll.
Exempel med en loop:
List<String> names = List.of("Alice", "Bob", "Charlie");
for (String name : names) {
System.out.println(name);
}
Exempel med Stream API:
List<String> names = List.of("Alice", "Bob", "Charlie");
names.stream().forEach(System.out::println);
I det första loop-exemplet beskriver vi uttryckligen hur vi ska iterera genom listan och skriva ut elementen, medan vi i det andra exemplet med Stream API helt enkelt anger vad som ska göras: iterera genom elementen och skriva ut dem. Detta gör koden mer deklarativ och lättläst.
Tack för dina kommentarer!
Fråga AI
Fråga AI
Fråga vad du vill eller prova någon av de föreslagna frågorna för att starta vårt samtal
Can you explain more about lazy evaluation in the Stream API?
What are some common terminal and intermediate operations in streams?
How does the Stream API improve code readability compared to traditional loops?
Awesome!
Completion rate improved to 2.33
Principer
Svep för att visa menyn
Principerna för att arbeta med Stream API bygger på centrala koncept inom funktionell programmering och lat utvärdering. Här följer en översikt av de viktigaste principerna för Stream API.
Lat utvärdering
En av de grundläggande principerna för Stream API är lat utvärdering.
Detta innebär att intermediära operationer såsom filter() eller map() inte utförs omedelbart. De bildar istället en kedja av åtgärder som endast exekveras när en terminal operation, såsom collect() eller forEach(), anropas.
Main.java
12345678910111213package com.example; import java.util.List; public class Main { public static void main(String[] args) { List<String> names = List.of("Alice", "Bob", "Charlie"); long count = names.stream() .filter(name -> name.startsWith("A")) // Forming the operation .count(); // Triggering execution System.out.println(count); // Output: 1 } }
Denna kod skapar en ström från en lista av strängar, filtrerar elementen för att behålla endast de som börjar med bokstaven A, och räknar hur många som uppfyller villkoret. Resultatet (1) skrivs ut eftersom endast Alice uppfyller villkoret.
Funktionell programmeringsstil
Stream API använder lambdauttryck och funktionella gränssnitt för databearbetning. Istället för det imperativa tillvägagångssättet med loopar beskrivs vad som ska göras med data:
Main.java
1234567891011121314package com.example; import java.util.List; public class Main { public static void main(String[] args) { List<String> fruits = List.of("apple", "banana", "cherry", "apricot", "blueberry"); List<String> result = fruits.stream() .map(String::toUpperCase) // Convert all strings to uppercase .skip(3) .toList(); // Collect the result into a new list System.out.println(result); } }
Denna kod skapar en ström från en lista av frukter, konverterar strängarna till versaler med hjälp av map(), och hoppar över de tre första elementen med skip(). Resultatet samlas i en ny lista och skrivs ut, med start från det fjärde elementet.
Omutbarhet av data
Stream API ändrar inte ursprungsdata. Alla operationer skapar en ny ström eller returnerar ett resultat utan att ändra samlingen eller arrayen. Detta ökar datasäkerheten och förhindrar oväntade bieffekter.
Main.java
12345678910111213package com.example; import java.util.List; public class Main { public static void main(String[] args) { List<String> names = List.of("Alice", "Bob", "Charlie"); List<String> updateNames = names.stream() .filter(name -> name.startsWith("A")) .toList(); System.out.println(names); // Output: [Alice, Bob, Charlie] } }
Stream API filtrerar list names för att skapa en ny stream, updateNames, som endast innehåller element som börjar med bokstaven A. Dock förblir original list names oförändrad, eftersom Stream API inte modifierar data direkt, vilket säkerställer datasäkerhet och förhindrar bieffekter.
Strömmar kan endast konsumeras en gång
En stream kan användas endast en gång. Efter att en terminal operation har utförts blir stream otillgänglig för vidare bearbetning.
Main.java
123456789101112package com.example; import java.util.List; import java.util.stream.Stream; public class Main { public static void main(String[] args) { Stream<String> stream = List.of("Alice", "Bob").stream(); stream.forEach(System.out::println); stream.forEach(System.out::println); // Error: Stream has already been used } }
Här skapas en stream från en lista av strängar och varje element skrivs ut till konsolen. Efter att streamen har använts första gången kan den inte återanvändas, vilket leder till ett fel om du försöker anropa forEach() igen.
Parallell bearbetning
Stream API stöder parallella streams, vilket möjliggör snabbare databearbetning på flerkärniga system. Detta behandlas mer ingående här
Main.java
1234567891011package com.example; import java.util.List; public class Main { public static void main(String[] args) { List<Integer> numbers = List.of(1, 2, 3, 4, 5); numbers.parallelStream() .forEach(System.out::println); // Elements are processed in parallel } }
Denna kod skapar en parallell ström från en lista med tal och skriver ut varje element till konsolen. Genom att använda parallelStream() möjliggörs parallell bearbetning av listelementen, vilket kan snabba upp exekveringen vid hantering av stora datamängder.
Kodrenhet och läsbarhet
Att använda Stream API gör koden mer deklarativ. Istället för att beskriva hur en uppgift ska utföras (som att använda loopar), beskriver du vad som faktiskt behöver göras. Detta förbättrar läsbarheten och förenklar kodunderhåll.
Exempel med en loop:
List<String> names = List.of("Alice", "Bob", "Charlie");
for (String name : names) {
System.out.println(name);
}
Exempel med Stream API:
List<String> names = List.of("Alice", "Bob", "Charlie");
names.stream().forEach(System.out::println);
I det första loop-exemplet beskriver vi uttryckligen hur vi ska iterera genom listan och skriva ut elementen, medan vi i det andra exemplet med Stream API helt enkelt anger vad som ska göras: iterera genom elementen och skriva ut dem. Detta gör koden mer deklarativ och lättläst.
Tack för dina kommentarer!