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

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ä käytössä on käyttäjänimien lista, ja täytyy laskea kunkin nimen pituus jatkoanalyysia 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 hyödyntä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 ketjuttamisen.

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 lista käyttäjänimistä, ja sinun tulee muuttaa ensimmäinen kirjain isoksi jokaisessa nimessä ja sen jälkeen 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-funktiota. Sen jälkeen tarkistetaan, onko muotoillussa käyttäjänimessä yli 5 merkkiä käyttäen isLongerThanFive-funktiota. Nämä kaksi funktiota yhdistetään käyttäen andThen()-metodia 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 siirretään addPrefix-funktiolle, joka lisää etuliitteen. Käytät compose()-metodia soveltaaksesi funktioita halutussa järjestyksessä.

Metodi identity()

Metodi identity() palauttaa funktion, joka palauttaa argumenttinsa sellaisenaan ilman muutoksia. Tätä käytetään, kun täytyy välittää funktio, joka ei muuta syötearvoa, mutta on tarpeen täyttää rajapinnan vaatimukset.

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 pitäen ohjelman rajapinnan 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ämpää ja tehokkaampaa käyttämällä suoraan identity()-metodia 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

Osio 1. Luku 6
some-alt