Maison  >  Article  >  Java  >  Interfaces fonctionnelles par défaut en Java

Interfaces fonctionnelles par défaut en Java

DDD
DDDoriginal
2024-09-19 06:26:32472parcourir

Default Functional Interfaces in Java

Je viens de terminer l'étude des interfaces fonctionnelles par défaut en Java, j'ai pensé à toutes les partager !
Les interfaces fonctionnelles sont des interfaces qui n'ont qu'une seule méthode abstraite. Ils sont nécessaires si vous avez affaire à des expressions lambda (programmation fonctionnelle). Ils simplifient le code et sont largement utilisés dans les flux. Bien que vous puissiez créer vos propres interfaces fonctionnelles, pourquoi s'inquiéter lorsque Java nous en fournit des interfaces importantes telles que Consommateur, Prédicat, Fonction et Fournisseur ?

1. Consommateur :

Consumer est une interface fonctionnelle qui représente une opération qui accepte un seul argument d'entrée et ne renvoie aucun résultat. Il est généralement utilisé pour effectuer une action sur l'argument donné (comme l'impression ou la journalisation) sans le modifier.

Signature : void accept(T t) (où T est le type générique)

2. Prédicat :

Predicate est une interface fonctionnelle qui représente une fonction à argument unique qui renvoie une valeur booléenne. Il est souvent utilisé pour filtrer ou évaluer des conditions (par exemple, vérifier si un nombre est pair).

Signature : test booléen(T t)

3. Fonction :

La fonction est une interface fonctionnelle qui représente une fonction qui accepte un argument et produit un résultat. Il est couramment utilisé pour les transformations (par exemple, convertir un type en un autre ou modifier des données).

Signature : R appliquer(T t)

4. Fournisseur :

Supplier est une interface fonctionnelle qui représente une fonction sans arguments d'entrée et renvoie un résultat. Il est souvent utilisé pour générer ou fournir des valeurs sans avoir besoin d’entrée.

Signature : T get()

Nous pouvons utiliser efficacement des interfaces fonctionnelles telles que Consommateur, Prédicat, Fonction et Fournisseur en définissant généralement des méthodes génériques qui acceptent ces interfaces comme paramètres. Cela nous permet de tirer parti de la puissance des génériques et de garantir que nos méthodes peuvent fonctionner avec différents types.

Voici un exemple du code complet qui démontre la fonctionnalité de chacun d'entre eux

import java.util.List;
import java.util.Random;
import java.util.function.*;

public class Main {
    public static void main(String[] args) {
        // Consumer
        usingConsumer((a) -> System.out.printf("Hello %s", a), "saami");
        System.out.println();
        // Bi-Consumer
        usingBiConsumer((a, b) -> System.out.printf("Name: %s, Age: %d", a, b), "saami", 20);
        System.out.println();
        // Predicate
        var result1 = usingPredicate((a) -> a % 2 == 0, 34);

        if (result1) {
            System.out.println("Even");
        } else {
            System.out.println("Odd");
        }
        // Bi-Predicate
        var result2 = usingBiPredicate((a, b) -> a > b, 12, 22);
        if (result2) {
            System.out.println("Greater");
        } else {
            System.out.println("Lesser");
        }
        // Function
        var result3 = usingFunction((a) -> a + ": this is a number", 5);
        System.out.println(result3);

        // Bi-Function
        var result4 = usingBiFunction((a, b) -> (a > b ? "Greater": "Lesser"), 5, 6);
        System.out.println(result4);

        // Unary-Operator
        var result5 = usingUnaryOperator((a) -> a+5, 10);
        System.out.println(result5);

        // Binary-Operator
        var result6 = usingBinaryOperator((a, b) -> a + b, 12, 32);
        System.out.println(result6);
        Random r = new Random();


        // Function as Predicate
        var result7 = usingFunctionAsPredicate((a) -> a > 99, 999);
        System.out.println(result7);

        // Using Consumer for printing of the list.
        printData((a) -> {
            for (var ele : a) {
                System.out.println(ele);
            }
        } , List.of("S1", "S2", "S3", "S4", "S5"));

        // Using Supplier as a random number generator
        String[] arr = {"saami", "john", "raymond", "puff"};
        System.out.println(getRandomOne(arr, () -> new Random().nextInt(arr.length)));

        // Using Custom Comparator
        System.out.println(usingCustomFunctionalInterface((a, b, c) -> a + b + c, "Saami", " Abbas", " Khan"));

    }

    public static <T> void usingConsumer(Consumer<T> consumer, T a) {
        // Method that takes consumer interface will return void.
        // Can print something constituting 'a'
        consumer.accept(a);
    }

    public static <T, L> void usingBiConsumer(BiConsumer<T, L> biConsumer, T a, L b) {
        biConsumer.accept(a, b);
    }

    public static <T> boolean usingPredicate(Predicate<T> predicate, T a) {
        return predicate.test(a);
    }

    public static <T, L> boolean usingBiPredicate(BiPredicate<T, L> biPredicate, T a, L b) {
        return biPredicate.test(a, b);
    }

    public static <T, R> R usingFunction(Function<T, R> function, T a) {
//        T for the parameter and R for the return type here the return type could be as same as T or
//        could be different like if T is Integer the R could be String 8 + ""
        return function.apply(a);
    }

    public static <T, U, R> R usingBiFunction(BiFunction<T, U, R> biFunction, T a, U b) {
        return biFunction.apply(a, b);
    }

    public static <T> T usingUnaryOperator(UnaryOperator<T> unaryOperator, T a) {
        return unaryOperator.apply(a);
    }

    public static <T> T usingBinaryOperator(BinaryOperator<T> binaryOperator, T a, T b) {
        return binaryOperator.apply(a, b);
    }

    public static <T, R> R usingFunctionAsPredicate(Function<T, R> prediFunction, T a) {
        return prediFunction.apply(a);
    }

    public static <T> void printData(Consumer<T> consumer, T a) {
        /*
         * Prints the data, (List.of()) using a for loop inside of lambda function.
         */
        consumer.accept(a);
    }

    public static String getRandomOne(String[] arr, Supplier<Integer> supplier) {
        return arr[supplier.get()];
    }

    @FunctionalInterface
    interface Concat<T> {
        T concat(T a, T b, T c);
    }
    public static <T> T usingCustomFunctionalInterface(Concat<T> concat, T a, T b, T c) {
        return concat.concat(a, b, c);
    }


}


Verdict final

Les interfaces fonctionnelles en Java sont un outil puissant pour simplifier le code et améliorer la lisibilité. Que vous traitiez des collections, effectuiez des transformations ou gériez des flux de données, ces interfaces facilitent la définition d'opérations concises.

En comprenant et en appliquant des interfaces fonctionnelles telles que Consommateur, Prédicat, Fonction, Fournisseur et personnalisées, vous pouvez tirer pleinement parti des fonctionnalités de programmation fonctionnelle de Java.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn