Periaatteet
Pyyhkäise näyttääksesi valikon
Stream API:n toimintaperiaatteet perustuvat funktionaalisen ohjelmoinnin ja laiskan arvioinnin keskeisiin käsitteisiin. Tarkastellaan Stream API:n tärkeimpiä periaatteita.
Laiska arviointi
Yksi Stream API:n keskeisistä periaatteista on laiska arviointi.
Tämä tarkoittaa, että välioperaatioita kuten filter() tai map() ei suoriteta välittömästi. Ne muodostavat vain ketjun toimintoja, jotka suoritetaan vasta, kun jokin pääteoperaatio, kuten collect() tai forEach(), kutsutaan.
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 } }
Tämä koodi luo virran (stream) merkkijonolistasta, suodattaa alkiot säilyttäen vain ne, jotka alkavat kirjaimella A, ja laskee, kuinka moni täyttää ehdon. Tulos (1) tulostetaan, koska vain Alice täyttää ehdon.
Funktionaalinen ohjelmointityyli
Stream API hyödyntää lambda-lausekkeita ja funktionaalisia rajapintoja datan käsittelyyn. Imperatiivisen lähestymistavan ja silmukoiden sijaan kuvataan, mitä datalla halutaan tehdä:
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); } }
Tämä koodi luo virran hedelmälistasta, muuntaa merkkijonot isoiksi kirjaimiksi käyttäen map():ia ja ohittaa kolme ensimmäistä alkiota metodilla skip(). Tulos kerätään uuteen listaan ja tulostetaan alkaen neljännestä alkiosta.
Datan muuttumattomuus
Stream API ei muuta alkuperäistä dataa. Kaikki operaatiot luovat uuden virran tai palauttavat tuloksen muuttamatta kokoelmaa tai taulukkoa. Tämä parantaa datan turvallisuutta ja estää odottamattomat sivuvaikutukset.
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 suodattaa listan names luodakseen uuden virran, updateNames, joka sisältää vain ne alkiot, jotka alkavat kirjaimella A. Kuitenkin alkuperäinen lista names säilyy muuttumattomana, sillä Stream API ei muokkaa dataa suoraan, mikä varmistaa datan turvallisuuden ja estää sivuvaikutukset.
Virrat ovat kertakäyttöisiä
Virtaa voidaan käyttää vain yhden kerran. Kun pääteoperaatio on suoritettu, virta ei ole enää käytettävissä jatkokäsittelyyn.
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 } }
Tässä luodaan virta merkkijonolistasta ja tulostetaan jokainen alkio konsoliin. Kun virtaa on käytetty ensimmäisen kerran, sitä ei voi käyttää uudelleen, mikä aiheuttaa virheen, jos yrität kutsua forEach() uudelleen.
Rinnakkaiskäsittely
Stream API tukee rinnakkaisvirtoja, mikä mahdollistaa nopeamman datan käsittelyn moniydinjärjestelmissä. Tätä käsitellään tarkemmin täällä
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 } }
Tämä koodi luo rinnakkaisvirran lukulistasta ja tulostaa jokaisen alkion konsoliin. Käyttämällä parallelStream()-metodia mahdollistetaan listan alkioiden rinnakkainen käsittely, mikä voi nopeuttaa suoritusta suurten datan määrien kanssa.
Koodin selkeys ja luettavuus
Stream API:n käyttö tekee koodista deklaratiivisempaa. Sen sijaan, että kuvailisit miten tehtävä suoritetaan (esimerkiksi silmukoiden avulla), määrittelet mitä tarkalleen halutaan tehdä. Tämä parantaa luettavuutta ja yksinkertaistaa koodin ylläpitoa.
Esimerkki silmukalla:
List<String> names = List.of("Alice", "Bob", "Charlie");
for (String name : names) {
System.out.println(name);
}
Esimerkki Stream API:n käytöstä:
List<String> names = List.of("Alice", "Bob", "Charlie");
names.stream().forEach(System.out::println);
Ensimmäisessä silmukkaesimerkissä kuvataan tarkasti, miten listaa käydään läpi ja tulostetaan sen alkiot, kun taas toisessa esimerkissä, jossa käytetään Stream API:a, määritellään vain, mitä pitää tehdä: käydä läpi alkiot ja tulostaa ne. Tämä tekee koodista deklaratiivisempaa ja luettavampaa.
Kiitos palautteestasi!
Kysy tekoälyä
Kysy tekoälyä
Kysy mitä tahansa tai kokeile jotakin ehdotetuista kysymyksistä aloittaaksesi keskustelumme