Principper
Principperne for at arbejde med Stream API er baseret på nøgle-koncepter inden for funktionel programmering og doven evaluering. Lad os se nærmere på de vigtigste principper for Stream API.
Doven evaluering
Et af de centrale principper for Stream API er doven evaluering.
Dette betyder, at mellemoperationer som filter() eller map() ikke udføres med det samme. De danner blot en kæde af handlinger, som kun udføres, når en terminal operation, såsom collect() eller forEach(), kaldes.
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 } }
Denne kode opretter en stream fra en liste af strenge, filtrerer elementerne for kun at beholde dem, der starter med bogstavet A, og tæller hvor mange der opfylder betingelsen. Resultatet (1) udskrives, da kun Alice opfylder betingelsen.
Funktionel programmeringsstil
Stream API anvender lambdaudtryk og funktionelle grænseflader til databehandling. I stedet for den imperative tilgang med løkker beskriver du, hvad der skal gøres med dataene:
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); } }
Denne kode opretter en stream fra en liste af frugter, konverterer strengene til store bogstaver ved hjælp af map(), og springer de første tre elementer over med skip(). Resultatet samles i en ny liste og udskrives, begyndende fra det fjerde element.
Uforanderlighed af data
Stream API ændrer ikke de oprindelige data. Alle operationer opretter en ny stream eller returnerer et resultat uden at ændre samlingen eller arrayet. Dette øger datasikkerheden og forhindrer uventede bivirkninger.
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 filtrerer list names for at oprette en ny stream, updateNames, der kun indeholder elementer, som starter med bogstavet A. Den oprindelige list names forbliver dog uændret, da Stream API ikke ændrer data direkte, hvilket sikrer datasikkerhed og forhindrer bivirkninger.
Streams kan kun forbruges én gang
En stream kan kun bruges én gang. Efter en terminal operation er udført, bliver streamen utilgængelig for yderligere behandling.
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 } }
Her oprettes en stream fra en liste af strenge og hvert element udskrives til konsollen. Når streamen er blevet brugt første gang, kan den ikke genbruges, hvilket medfører en fejl, hvis du forsøger at kalde forEach() igen.
Parallel behandling
Stream API understøtter parallelle streams, hvilket muliggør hurtigere databehandling på multikerne-systemer. Dette uddybes nærmere her
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 } }
Denne kode opretter en parallel stream fra en liste af tal og udskriver hvert element til konsollen. Ved at bruge parallelStream() muliggøres parallel behandling af listeelementerne, hvilket kan øge hastigheden ved håndtering af store datasæt.
Kodekvalitet og læsbarhed
Brug af Stream API gør koden mere deklarativ. I stedet for at beskrive hvordan en opgave udføres (som ved brug af løkker), beskrives hvad der præcist skal gøres. Dette forbedrer læsbarheden og forenkler vedligeholdelsen af koden.
Eksempel med en løkke:
List<String> names = List.of("Alice", "Bob", "Charlie");
for (String name : names) {
System.out.println(name);
}
Eksempel ved brug af Stream API:
List<String> names = List.of("Alice", "Bob", "Charlie");
names.stream().forEach(System.out::println);
I det første loop-eksempel beskriver vi eksplicit hvordan vi skal iterere gennem listen og udskrive elementerne, mens vi i det andet eksempel med Stream API blot angiver hvad der skal gøres: iterere gennem elementerne og udskrive dem. Dette gør koden mere deklarativ og læsbar.
Tak for dine kommentarer!
Spørg AI
Spørg AI
Spørg om hvad som helst eller prøv et af de foreslåede spørgsmål for at starte vores chat
Awesome!
Completion rate improved to 2.33
Principper
Stryg for at vise menuen
Principperne for at arbejde med Stream API er baseret på nøgle-koncepter inden for funktionel programmering og doven evaluering. Lad os se nærmere på de vigtigste principper for Stream API.
Doven evaluering
Et af de centrale principper for Stream API er doven evaluering.
Dette betyder, at mellemoperationer som filter() eller map() ikke udføres med det samme. De danner blot en kæde af handlinger, som kun udføres, når en terminal operation, såsom collect() eller forEach(), kaldes.
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 } }
Denne kode opretter en stream fra en liste af strenge, filtrerer elementerne for kun at beholde dem, der starter med bogstavet A, og tæller hvor mange der opfylder betingelsen. Resultatet (1) udskrives, da kun Alice opfylder betingelsen.
Funktionel programmeringsstil
Stream API anvender lambdaudtryk og funktionelle grænseflader til databehandling. I stedet for den imperative tilgang med løkker beskriver du, hvad der skal gøres med dataene:
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); } }
Denne kode opretter en stream fra en liste af frugter, konverterer strengene til store bogstaver ved hjælp af map(), og springer de første tre elementer over med skip(). Resultatet samles i en ny liste og udskrives, begyndende fra det fjerde element.
Uforanderlighed af data
Stream API ændrer ikke de oprindelige data. Alle operationer opretter en ny stream eller returnerer et resultat uden at ændre samlingen eller arrayet. Dette øger datasikkerheden og forhindrer uventede bivirkninger.
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 filtrerer list names for at oprette en ny stream, updateNames, der kun indeholder elementer, som starter med bogstavet A. Den oprindelige list names forbliver dog uændret, da Stream API ikke ændrer data direkte, hvilket sikrer datasikkerhed og forhindrer bivirkninger.
Streams kan kun forbruges én gang
En stream kan kun bruges én gang. Efter en terminal operation er udført, bliver streamen utilgængelig for yderligere behandling.
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 } }
Her oprettes en stream fra en liste af strenge og hvert element udskrives til konsollen. Når streamen er blevet brugt første gang, kan den ikke genbruges, hvilket medfører en fejl, hvis du forsøger at kalde forEach() igen.
Parallel behandling
Stream API understøtter parallelle streams, hvilket muliggør hurtigere databehandling på multikerne-systemer. Dette uddybes nærmere her
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 } }
Denne kode opretter en parallel stream fra en liste af tal og udskriver hvert element til konsollen. Ved at bruge parallelStream() muliggøres parallel behandling af listeelementerne, hvilket kan øge hastigheden ved håndtering af store datasæt.
Kodekvalitet og læsbarhed
Brug af Stream API gør koden mere deklarativ. I stedet for at beskrive hvordan en opgave udføres (som ved brug af løkker), beskrives hvad der præcist skal gøres. Dette forbedrer læsbarheden og forenkler vedligeholdelsen af koden.
Eksempel med en løkke:
List<String> names = List.of("Alice", "Bob", "Charlie");
for (String name : names) {
System.out.println(name);
}
Eksempel ved brug af Stream API:
List<String> names = List.of("Alice", "Bob", "Charlie");
names.stream().forEach(System.out::println);
I det første loop-eksempel beskriver vi eksplicit hvordan vi skal iterere gennem listen og udskrive elementerne, mens vi i det andet eksempel med Stream API blot angiver hvad der skal gøres: iterere gennem elementerne og udskrive dem. Dette gør koden mere deklarativ og læsbar.
Tak for dine kommentarer!