Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Leer Functie: Gegevens Transformatie | Sectie
Stream-API in Java

bookFunctie: Gegevens Transformatie

Veeg om het menu te tonen

Hoewel Predicate ons helpt bij het evalueren van booleaanse expressies, stelt Function ons in staat om gegevens te transformeren door bewerkingen toe te passen die resultaten opleveren op basis van de invoer.

Function wordt vaak gebruikt voor gegevens transformatie, zoals typeconversie, berekeningen of waardeverwerking.

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

De interface Function<T, R> in Java vertegenwoordigt een functionele interface die een argument van het type T accepteert en een resultaat van het type R retourneert.

De methode apply(T t) voert de datatransformatie uit door de invoerwaarde te nemen en het resultaat terug te geven. Dit maakt het mogelijk om flexibele functies te creëren voor het verwerken van gegevens van verschillende typen.

Praktische Toepassing

Stel, je hebt een lijst met gebruikersnamen en je moet de lengte van elke naam berekenen voor verdere analyse of gegevensverwerking.

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

In dit voorbeeld is er een lijst met gebruikersnamen. Voor elke naam wordt de functie nameLength gebruikt, die het aantal tekens in de naam bepaalt met de methode length(). Met de methode forEach wordt over elk element van de lijst geïtereerd en wordt een bericht afgedrukt dat aangeeft hoeveel tekens elke naam bevat.

Functies combineren

De interface Function biedt verschillende methoden voor het combineren van functies, waarmee een keten van bewerkingen kan worden gemaakt.

Methode andThen()

Met de methode andThen() kunnen twee functies worden gecombineerd door eerst de ene functie toe te passen en vervolgens het resultaat door te geven aan de tweede functie. Dit is nuttig wanneer meerdere bewerkingen opeenvolgend moeten worden uitgevoerd.

Voorbeeld

Je hebt een lijst met gebruikersnamen en je moet de eerste letter van elke naam kapitaliseren en vervolgens controleren of de naam meer dan 5 tekens bevat.

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

Eerst kapitaliseer je de eerste letter van elke gebruikersnaam met capitalizeFirstLetter. Vervolgens controleer je of de opgemaakte gebruikersnaam meer dan 5 tekens bevat met isLongerThanFive. De twee functies worden gecombineerd met andThen() voor sequentiële verwerking.

Methode compose()

De methode compose() maakt het mogelijk om functies te combineren, maar in de omgekeerde volgorde: de tweede functie wordt eerst toegepast, en het resultaat wordt vervolgens doorgegeven aan de eerste functie.

Voorbeeld

Er is een string en het doel is om eerst de lengte ervan te berekenen en vervolgens een voorvoegsel toe te voegen aan het resultaat.

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

In dit voorbeeld wordt eerst de lengte van de string berekend met stringLength, waarna het resultaat wordt doorgegeven aan de functie addPrefix, die een voorvoegsel toevoegt. Met compose() worden de functies in de gewenste volgorde toegepast.

Methode identity()

De methode identity() retourneert een functie die eenvoudigweg haar argument zonder enige wijzigingen teruggeeft. Dit is nuttig wanneer een functie vereist is die de invoervaarde niet aanpast, maar wel nodig is om aan de interface te voldoen.

Voorbeeld

Stel dat je een lijst met gebruikersnamen moet verwerken door verschillende transformaties toe te passen: één om de namen naar hoofdletters te converteren, een andere om het achtervoegsel "User" toe te voegen, en een derde met de functie identity() om de naam onveranderd te laten. De taak is om deze functies op elke naam in de lijst toe te passen, terwijl de interface van het programma voor elke transformatie consistent blijft.

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

Zoals je kunt zien, bestaat de output uit drie opgemaakte lijsten met gebruikersnamen. De laatste lijst bevat de originele namen, waarbij de methode identity() van pas komt, omdat deze het mogelijk maakt om de namen terug te geven zonder extra logica toe te voegen voor het verwerken van de onveranderde waarden. Dit maakt de code netter en efficiënter door direct identity() te gebruiken wanneer er geen transformatie nodig is.

1. Wat doet de methode andThen() in de Function-interface?

2. Wat is het resultaat bij het toepassen van de methode identity()?

3. Wat doet de methode compose()?

question mark

Wat doet de methode andThen() in de Function-interface?

Select the correct answer

question mark

Wat is het resultaat bij het toepassen van de methode identity()?

Select the correct answer

question mark

Wat doet de methode compose()?

Select the correct answer

Was alles duidelijk?

Hoe kunnen we het verbeteren?

Bedankt voor je feedback!

Sectie 1. Hoofdstuk 6

Vraag AI

expand

Vraag AI

ChatGPT

Vraag wat u wilt of probeer een van de voorgestelde vragen om onze chat te starten.

Sectie 1. Hoofdstuk 6
some-alt