Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Oppiskele Periaatteet | Osio
Stream API Javassa

bookPeriaatteet

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

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 } }

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

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); } }

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

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 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

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 } }

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

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 } }

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.

Oliko kaikki selvää?

Miten voimme parantaa sitä?

Kiitos palautteestasi!

Osio 1. Luku 2

Kysy tekoälyä

expand

Kysy tekoälyä

ChatGPT

Kysy mitä tahansa tai kokeile jotakin ehdotetuista kysymyksistä aloittaaksesi keskustelumme

Osio 1. Luku 2
some-alt