Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Lære Principper | Grundlæggende og Funktionelle Kapaciteter af Stream API
Stream API

bookPrincipper

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

Main.java

copy
12345678910111213
package 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

Main.java

copy
1234567891011121314
package 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

Main.java

copy
12345678910111213
package 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

Main.java

copy
123456789101112
package 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 databehandlingmultikerne-systemer. Dette uddybes nærmere her

Main.java

Main.java

copy
1234567891011
package 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.

Var alt klart?

Hvordan kan vi forbedre det?

Tak for dine kommentarer!

Sektion 1. Kapitel 2

Spørg AI

expand

Spørg AI

ChatGPT

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

bookPrincipper

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

Main.java

copy
12345678910111213
package 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

Main.java

copy
1234567891011121314
package 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

Main.java

copy
12345678910111213
package 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

Main.java

copy
123456789101112
package 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 databehandlingmultikerne-systemer. Dette uddybes nærmere her

Main.java

Main.java

copy
1234567891011
package 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.

Var alt klart?

Hvordan kan vi forbedre det?

Tak for dine kommentarer!

Sektion 1. Kapitel 2
some-alt