Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Oppiskele Funktio: Datan Muuntaminen | Stream API:n Perusteet ja Toiminnalliset Ominaisuudet
Stream API

bookFunktio: Datan Muuntaminen

Vaikka Predicate auttaa arvioimaan totuusarvolausekkeita, Function mahdollistaa datan muuntamisen soveltamalla operaatioita, jotka palauttavat tuloksia annetun syötteen perusteella.

Function-rajapintaa käytetään yleisesti datan muuntamiseen, kuten tyyppimuunnoksiin, laskutoimituksiin tai arvojen käsittelyyn.

@FunctionalInterface
public interface Function<T, R> {
    R apply(T t);
}

Rajapinta Function<T, R> Java-kielessä edustaa funktionaalista rajapintaa, joka ottaa parametrin tyyppiä T ja palauttaa tuloksen tyyppiä R.

Metodi apply(T t) suorittaa datan muunnoksen ottamalla syötearvon ja palauttamalla tuloksen. Tämä mahdollistaa joustavien funktioiden luomisen erilaisten datan käsittelyyn.

Käytännön sovellus

Oletetaan, että sinulla on käyttäjänimien lista, ja sinun täytyy laskea jokaisen nimen pituus jatkoanalyysiä tai datan käsittelyä varten.

Main.java

Main.java

copy
1234567891011121314151617
package com.example; import java.util.Arrays; import java.util.List; import java.util.function.Function; public class Main { public static void main(String[] args) { List<String> users = Arrays.asList("Alice", "Bob", "Charlie", "David"); Function<String, Integer> nameLength = name -> name.length(); users.forEach(user -> { System.out.println(user + " has " + nameLength.apply(user) + " characters."); }); } }

Tässä esimerkissä käytössä on käyttäjänimien lista. Jokaiselle nimelle käytetään nameLength-funktiota, joka laskee nimen merkkien määrän käyttäen length()-metodia. forEach-metodin avulla käsitellään jokainen listan alkio ja tulostetaan viesti, joka näyttää kuinka monta merkkiä kukin nimi sisältää.

Funktioiden yhdistäminen

Function-rajapinta tarjoaa useita menetelmiä funktioiden yhdistämiseen, mikä mahdollistaa operaatioiden ketjun luomisen.

Metodi andThen()

andThen()-metodi mahdollistaa kahden funktion yhdistämisen siten, että ensin suoritetaan yksi funktio ja sen tulos välitetään toiselle funktiolle. Tämä on hyödyllistä, kun täytyy suorittaa useita operaatioita peräkkäin.

Esimerkki

Sinulla on käyttäjänimien lista, ja sinun tulee muuttaa ensimmäinen kirjain isoksi jokaisessa nimessä ja sitten tarkistaa, onko nimessä yli 5 merkkiä.

Main.java

Main.java

copy
1234567891011121314151617181920212223
package com.example; import java.util.Arrays; import java.util.List; import java.util.function.Function; public class Main { public static void main(String[] args) { List<String> usernames = Arrays.asList("john", "alice", "bob", "charlie", "david"); // Capitalize first letter Function<String, String> capitalizeFirstLetter = name -> name.substring(0, 1).toUpperCase() + name.substring(1); // Check if the username has more than 5 characters Function<String, Boolean> isLongerThanFive = name -> name.length() > 5; // Combine functions using `andThen()` Function<String, Boolean> formattedNameThenCheckLength = capitalizeFirstLetter.andThen(isLongerThanFive); usernames.forEach(user -> { System.out.println(user + " -> " + formattedNameThenCheckLength.apply(user)); }); } }

Ensin muutetaan käyttäjänimen ensimmäinen kirjain isoksi käyttäen capitalizeFirstLetter. Sen jälkeen tarkistetaan, onko muotoillussa käyttäjänimessä yli 5 merkkiä käyttäen isLongerThanFive. Nämä kaksi funktiota yhdistetään käyttäen andThen() peräkkäiseen käsittelyyn.

Metodi compose()

Metodi compose() mahdollistaa funktioiden yhdistämisen, mutta käänteisessä järjestyksessä: toinen funktio suoritetaan ensin, ja tulos välitetään sitten ensimmäiselle funktiolle.

Esimerkki

Sinulla on merkkijono, ja haluat ensin laskea sen pituuden ja sitten lisätä etuliitteen tulokseen.

Main.java

Main.java

copy
123456789101112131415161718
package com.example; import java.util.function.Function; public class Main { public static void main(String[] args) { String phrase = "Hello World"; // First, calculate the length, then add a prefix Function<String, Integer> stringLength = String::length; Function<Integer, String> addPrefix = length -> "Length: " + length; // Combine functions using compose Function<String, String> lengthThenPrefix = addPrefix.compose(stringLength); System.out.println(lengthThenPrefix.apply(phrase)); // Output: Length: 11 } }

Tässä esimerkissä ensin lasketaan merkkijonon pituus käyttäen stringLength-funktiota, ja sitten tulos välitetään addPrefix-funktiolle, joka lisää etuliitteen. Käytät compose()-funktiota soveltaaksesi funktioita halutussa järjestyksessä.

Metodi identity()

Metodi identity() palauttaa funktion, joka palauttaa argumenttinsa ilman muutoksia. Tämä on hyödyllistä, kun täytyy välittää funktio, joka ei muuta syötearvoa, mutta on tarpeen rajapinnan yhteensopivuuden vuoksi.

Esimerkki

Kuvittele, että täytyy käsitellä käyttäjänimien listaa soveltamalla useita muunnoksia: yksi muuntaa nimet isoiksi kirjaimiksi, toinen lisää "User"-päätteen, ja kolmas käyttää identity()-funktiota jättäen nimen muuttumattomaksi. Tarkoituksena on soveltaa näitä funktioita jokaiseen nimeen listassa ja pitää ohjelman rajapinta yhdenmukaisena jokaisessa muunnoksessa.

Main.java

Main.java

copy
1234567891011121314151617181920212223242526272829303132
package com.example; import java.util.List; import java.util.Arrays; import java.util.function.Function; public class Main { public static void main(String[] args) { List<String> usernames = Arrays.asList("alice", "bob", "charlie", "david", "eve"); // `Function` to convert the username to uppercase Function<String, String> uppercaseFunction = name -> name.toUpperCase(); // `Function` to add the "User" suffix Function<String, String> suffixFunction = name -> name + "User"; // Identity `Function`, which does nothing Function<String, String> identityFunction = Function.identity(); // Applying a combination of functions List<Function<String, ?>> transformations = Arrays.asList(uppercaseFunction, suffixFunction, identityFunction); // Applying each `Function` from the list for (Function<String, ?> transformation : transformations) { System.out.println("--------------------"); usernames.stream() .map(name -> transformation.apply(name)) .forEach(System.out::println); } } }

Kuten huomaat, tuloste koostuu kolmesta muotoillusta käyttäjänimiluettelosta. Viimeinen luettelo sisältää alkuperäiset nimet, jolloin identity()-metodista on hyötyä, koska sen avulla voidaan palauttaa nimet ilman ylimääräistä logiikkaa muuttumattomien arvojen käsittelyyn. Tämä tekee koodista selkeämmän ja tehokkaamman, kun identity()-metodia käytetään suoraan silloin, kun muunnosta ei tarvita.

1. Mitä andThen()-metodi tekee Function-rajapinnassa?

2. Mikä on tulos, kun käytetään identity()-metodia?

3. Mitä compose()-metodi tekee?

question mark

Mitä andThen()-metodi tekee Function-rajapinnassa?

Select the correct answer

question mark

Mikä on tulos, kun käytetään identity()-metodia?

Select the correct answer

question mark

Mitä compose()-metodi tekee?

Select the correct answer

Oliko kaikki selvää?

Miten voimme parantaa sitä?

Kiitos palautteestasi!

Osio 1. Luku 6

Kysy tekoälyä

expand

Kysy tekoälyä

ChatGPT

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

Awesome!

Completion rate improved to 2.33

bookFunktio: Datan Muuntaminen

Pyyhkäise näyttääksesi valikon

Vaikka Predicate auttaa arvioimaan totuusarvolausekkeita, Function mahdollistaa datan muuntamisen soveltamalla operaatioita, jotka palauttavat tuloksia annetun syötteen perusteella.

Function-rajapintaa käytetään yleisesti datan muuntamiseen, kuten tyyppimuunnoksiin, laskutoimituksiin tai arvojen käsittelyyn.

@FunctionalInterface
public interface Function<T, R> {
    R apply(T t);
}

Rajapinta Function<T, R> Java-kielessä edustaa funktionaalista rajapintaa, joka ottaa parametrin tyyppiä T ja palauttaa tuloksen tyyppiä R.

Metodi apply(T t) suorittaa datan muunnoksen ottamalla syötearvon ja palauttamalla tuloksen. Tämä mahdollistaa joustavien funktioiden luomisen erilaisten datan käsittelyyn.

Käytännön sovellus

Oletetaan, että sinulla on käyttäjänimien lista, ja sinun täytyy laskea jokaisen nimen pituus jatkoanalyysiä tai datan käsittelyä varten.

Main.java

Main.java

copy
1234567891011121314151617
package com.example; import java.util.Arrays; import java.util.List; import java.util.function.Function; public class Main { public static void main(String[] args) { List<String> users = Arrays.asList("Alice", "Bob", "Charlie", "David"); Function<String, Integer> nameLength = name -> name.length(); users.forEach(user -> { System.out.println(user + " has " + nameLength.apply(user) + " characters."); }); } }

Tässä esimerkissä käytössä on käyttäjänimien lista. Jokaiselle nimelle käytetään nameLength-funktiota, joka laskee nimen merkkien määrän käyttäen length()-metodia. forEach-metodin avulla käsitellään jokainen listan alkio ja tulostetaan viesti, joka näyttää kuinka monta merkkiä kukin nimi sisältää.

Funktioiden yhdistäminen

Function-rajapinta tarjoaa useita menetelmiä funktioiden yhdistämiseen, mikä mahdollistaa operaatioiden ketjun luomisen.

Metodi andThen()

andThen()-metodi mahdollistaa kahden funktion yhdistämisen siten, että ensin suoritetaan yksi funktio ja sen tulos välitetään toiselle funktiolle. Tämä on hyödyllistä, kun täytyy suorittaa useita operaatioita peräkkäin.

Esimerkki

Sinulla on käyttäjänimien lista, ja sinun tulee muuttaa ensimmäinen kirjain isoksi jokaisessa nimessä ja sitten tarkistaa, onko nimessä yli 5 merkkiä.

Main.java

Main.java

copy
1234567891011121314151617181920212223
package com.example; import java.util.Arrays; import java.util.List; import java.util.function.Function; public class Main { public static void main(String[] args) { List<String> usernames = Arrays.asList("john", "alice", "bob", "charlie", "david"); // Capitalize first letter Function<String, String> capitalizeFirstLetter = name -> name.substring(0, 1).toUpperCase() + name.substring(1); // Check if the username has more than 5 characters Function<String, Boolean> isLongerThanFive = name -> name.length() > 5; // Combine functions using `andThen()` Function<String, Boolean> formattedNameThenCheckLength = capitalizeFirstLetter.andThen(isLongerThanFive); usernames.forEach(user -> { System.out.println(user + " -> " + formattedNameThenCheckLength.apply(user)); }); } }

Ensin muutetaan käyttäjänimen ensimmäinen kirjain isoksi käyttäen capitalizeFirstLetter. Sen jälkeen tarkistetaan, onko muotoillussa käyttäjänimessä yli 5 merkkiä käyttäen isLongerThanFive. Nämä kaksi funktiota yhdistetään käyttäen andThen() peräkkäiseen käsittelyyn.

Metodi compose()

Metodi compose() mahdollistaa funktioiden yhdistämisen, mutta käänteisessä järjestyksessä: toinen funktio suoritetaan ensin, ja tulos välitetään sitten ensimmäiselle funktiolle.

Esimerkki

Sinulla on merkkijono, ja haluat ensin laskea sen pituuden ja sitten lisätä etuliitteen tulokseen.

Main.java

Main.java

copy
123456789101112131415161718
package com.example; import java.util.function.Function; public class Main { public static void main(String[] args) { String phrase = "Hello World"; // First, calculate the length, then add a prefix Function<String, Integer> stringLength = String::length; Function<Integer, String> addPrefix = length -> "Length: " + length; // Combine functions using compose Function<String, String> lengthThenPrefix = addPrefix.compose(stringLength); System.out.println(lengthThenPrefix.apply(phrase)); // Output: Length: 11 } }

Tässä esimerkissä ensin lasketaan merkkijonon pituus käyttäen stringLength-funktiota, ja sitten tulos välitetään addPrefix-funktiolle, joka lisää etuliitteen. Käytät compose()-funktiota soveltaaksesi funktioita halutussa järjestyksessä.

Metodi identity()

Metodi identity() palauttaa funktion, joka palauttaa argumenttinsa ilman muutoksia. Tämä on hyödyllistä, kun täytyy välittää funktio, joka ei muuta syötearvoa, mutta on tarpeen rajapinnan yhteensopivuuden vuoksi.

Esimerkki

Kuvittele, että täytyy käsitellä käyttäjänimien listaa soveltamalla useita muunnoksia: yksi muuntaa nimet isoiksi kirjaimiksi, toinen lisää "User"-päätteen, ja kolmas käyttää identity()-funktiota jättäen nimen muuttumattomaksi. Tarkoituksena on soveltaa näitä funktioita jokaiseen nimeen listassa ja pitää ohjelman rajapinta yhdenmukaisena jokaisessa muunnoksessa.

Main.java

Main.java

copy
1234567891011121314151617181920212223242526272829303132
package com.example; import java.util.List; import java.util.Arrays; import java.util.function.Function; public class Main { public static void main(String[] args) { List<String> usernames = Arrays.asList("alice", "bob", "charlie", "david", "eve"); // `Function` to convert the username to uppercase Function<String, String> uppercaseFunction = name -> name.toUpperCase(); // `Function` to add the "User" suffix Function<String, String> suffixFunction = name -> name + "User"; // Identity `Function`, which does nothing Function<String, String> identityFunction = Function.identity(); // Applying a combination of functions List<Function<String, ?>> transformations = Arrays.asList(uppercaseFunction, suffixFunction, identityFunction); // Applying each `Function` from the list for (Function<String, ?> transformation : transformations) { System.out.println("--------------------"); usernames.stream() .map(name -> transformation.apply(name)) .forEach(System.out::println); } } }

Kuten huomaat, tuloste koostuu kolmesta muotoillusta käyttäjänimiluettelosta. Viimeinen luettelo sisältää alkuperäiset nimet, jolloin identity()-metodista on hyötyä, koska sen avulla voidaan palauttaa nimet ilman ylimääräistä logiikkaa muuttumattomien arvojen käsittelyyn. Tämä tekee koodista selkeämmän ja tehokkaamman, kun identity()-metodia käytetään suoraan silloin, kun muunnosta ei tarvita.

1. Mitä andThen()-metodi tekee Function-rajapinnassa?

2. Mikä on tulos, kun käytetään identity()-metodia?

3. Mitä compose()-metodi tekee?

question mark

Mitä andThen()-metodi tekee Function-rajapinnassa?

Select the correct answer

question mark

Mikä on tulos, kun käytetään identity()-metodia?

Select the correct answer

question mark

Mitä compose()-metodi tekee?

Select the correct answer

Oliko kaikki selvää?

Miten voimme parantaa sitä?

Kiitos palautteestasi!

Osio 1. Luku 6
some-alt