Prinsipper
Prinsippene for arbeid med Stream API er basert på sentrale konsepter innen funksjonell programmering og lat evaluering. La oss se nærmere på de viktigste prinsippene for Stream API.
Lat evaluering
Et av de grunnleggende prinsippene for Stream API er lat evaluering.
Dette innebærer at mellomliggende operasjoner som filter() eller map() ikke utføres umiddelbart. De danner kun en kjede av handlinger som først utføres når en terminal operasjon, som collect() eller forEach(), kalles.
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 koden oppretter en stream fra en liste med strenger, filtrerer elementene for å beholde kun de som starter med bokstaven A, og teller hvor mange som oppfyller betingelsen. Resultatet (1) skrives ut siden kun Alice oppfyller betingelsen.
Funksjonell programmeringsstil
Stream API benytter lambda-uttrykk og funksjonelle grensesnitt for databehandling. I stedet for den imperative tilnærmingen med løkker, beskriver du hva som skal gjø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 koden oppretter en stream fra en liste med frukter, konverterer strengene til store bokstaver ved hjelp av map(), og hopper over de tre første elementene med skip(). Resultatet samles i en ny liste og skrives ut, med start fra det fjerde elementet.
Uforanderlighet av data
Stream API endrer ikke originaldataene. Alle operasjoner oppretter en ny stream eller returnerer et resultat uten å endre samlingen eller arrayet. Dette øker datasikkerheten 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 å opprette en ny stream, updateNames, som kun inneholder elementer som starter med bokstaven A. Den opprinnelige listen list names forblir imidlertid uendret, ettersom Stream API ikke endrer data direkte, noe som sikrer datasikkerhet og forhindrer bivirkninger.
Strømmer kan kun konsumeres én gang
En stream kan kun brukes én gang. Etter at en terminaloperasjon er utført, blir streamen utilgjengelig for videre prosessering.
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 opprettes en stream fra en liste med strenger og hvert element skrives ut til konsollen. Etter at streamen er brukt første gang, kan den ikke gjenbrukes, noe som fører til en feil hvis du forsøker å kalle forEach() igjen.
Parallell prosessering
Stream API støtter parallelle streams, noe som muliggjør raskere databehandling på flerkjernesystemer. Dette utforskes 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 koden oppretter en parallell strøm fra en liste med tall og skriver ut hvert element til konsollen. Ved å bruke parallelStream() muliggjøres parallell behandling av listeelementene, noe som kan øke hastigheten på utførelsen ved håndtering av store datasett.
Kodekvalitet og lesbarhet
Bruk av Stream API gjør koden mer deklarativ. I stedet for å beskrive hvordan en oppgave skal utføres (som ved bruk av løkker), beskriver du hva som faktisk skal gjøres. Dette forbedrer lesbarheten og forenkler vedlikehold av koden.
Eksempel med en løkke:
List<String> names = List.of("Alice", "Bob", "Charlie");
for (String name : names) {
System.out.println(name);
}
Eksempel med Stream API:
List<String> names = List.of("Alice", "Bob", "Charlie");
names.stream().forEach(System.out::println);
I det første løkkeeksempelet beskriver vi eksplisitt hvordan vi skal iterere gjennom listen og skrive ut elementene, mens vi i det andre eksempelet med Stream API kun angir hva som skal gjøres: iterere gjennom elementene og skrive dem ut. Dette gjør koden mer deklarativ og lesbar.
Takk for tilbakemeldingene dine!
Spør AI
Spør AI
Spør om hva du vil, eller prøv ett av de foreslåtte spørsmålene for å starte chatten vår
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
Prinsipper
Sveip for å vise menyen
Prinsippene for arbeid med Stream API er basert på sentrale konsepter innen funksjonell programmering og lat evaluering. La oss se nærmere på de viktigste prinsippene for Stream API.
Lat evaluering
Et av de grunnleggende prinsippene for Stream API er lat evaluering.
Dette innebærer at mellomliggende operasjoner som filter() eller map() ikke utføres umiddelbart. De danner kun en kjede av handlinger som først utføres når en terminal operasjon, som collect() eller forEach(), kalles.
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 koden oppretter en stream fra en liste med strenger, filtrerer elementene for å beholde kun de som starter med bokstaven A, og teller hvor mange som oppfyller betingelsen. Resultatet (1) skrives ut siden kun Alice oppfyller betingelsen.
Funksjonell programmeringsstil
Stream API benytter lambda-uttrykk og funksjonelle grensesnitt for databehandling. I stedet for den imperative tilnærmingen med løkker, beskriver du hva som skal gjø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 koden oppretter en stream fra en liste med frukter, konverterer strengene til store bokstaver ved hjelp av map(), og hopper over de tre første elementene med skip(). Resultatet samles i en ny liste og skrives ut, med start fra det fjerde elementet.
Uforanderlighet av data
Stream API endrer ikke originaldataene. Alle operasjoner oppretter en ny stream eller returnerer et resultat uten å endre samlingen eller arrayet. Dette øker datasikkerheten 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 å opprette en ny stream, updateNames, som kun inneholder elementer som starter med bokstaven A. Den opprinnelige listen list names forblir imidlertid uendret, ettersom Stream API ikke endrer data direkte, noe som sikrer datasikkerhet og forhindrer bivirkninger.
Strømmer kan kun konsumeres én gang
En stream kan kun brukes én gang. Etter at en terminaloperasjon er utført, blir streamen utilgjengelig for videre prosessering.
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 opprettes en stream fra en liste med strenger og hvert element skrives ut til konsollen. Etter at streamen er brukt første gang, kan den ikke gjenbrukes, noe som fører til en feil hvis du forsøker å kalle forEach() igjen.
Parallell prosessering
Stream API støtter parallelle streams, noe som muliggjør raskere databehandling på flerkjernesystemer. Dette utforskes 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 koden oppretter en parallell strøm fra en liste med tall og skriver ut hvert element til konsollen. Ved å bruke parallelStream() muliggjøres parallell behandling av listeelementene, noe som kan øke hastigheten på utførelsen ved håndtering av store datasett.
Kodekvalitet og lesbarhet
Bruk av Stream API gjør koden mer deklarativ. I stedet for å beskrive hvordan en oppgave skal utføres (som ved bruk av løkker), beskriver du hva som faktisk skal gjøres. Dette forbedrer lesbarheten og forenkler vedlikehold av koden.
Eksempel med en løkke:
List<String> names = List.of("Alice", "Bob", "Charlie");
for (String name : names) {
System.out.println(name);
}
Eksempel med Stream API:
List<String> names = List.of("Alice", "Bob", "Charlie");
names.stream().forEach(System.out::println);
I det første løkkeeksempelet beskriver vi eksplisitt hvordan vi skal iterere gjennom listen og skrive ut elementene, mens vi i det andre eksempelet med Stream API kun angir hva som skal gjøres: iterere gjennom elementene og skrive dem ut. Dette gjør koden mer deklarativ og lesbar.
Takk for tilbakemeldingene dine!