JavaRush /Blog Java /Random-FR /Pause café #182. Interfaces fonctionnelles en Java

Pause café #182. Interfaces fonctionnelles en Java

Publié dans le groupe Random-FR
Source : DZone Voici un aperçu des interfaces fonctionnelles en Java : objectif, exemples, expressions lambda et une liste d'interfaces prédéfinies. Pause café #182.  Interfaces fonctionnelles en Java - 1En tant que langage de programmation orienté objet, Java ne pouvait auparavant pas avoir de fonctions indépendantes car tout, à l'exception de certains types de données et méthodes primitifs, tourne autour des classes et des objets. Cependant, Java 8 a introduit un nouveau concept appelé Functional Interface ainsi que d'autres fonctionnalités telles que les expressions Lambda, l'API Time, l'API Stream, etc. Quelles sont ces interfaces fonctionnelles et comment les définir ? Découvrons-le!

Qu'est-ce qu'une interface ?

Une interface est un ensemble de règles qui déterminent l'interaction des éléments du système. Il est également connu comme les grandes lignes d'une classe contenant des méthodes abstraites et des constantes statiques. Une interface peut contenir une ou plusieurs méthodes abstraites. Les interfaces vous permettent également de définir les exigences pour les classes, c'est-à-dire les méthodes requises de la classe. En termes simples, une interface est comme un contrat qui doit être respecté par chaque classe d'implémentation. Voici un exemple :
Interface A1
{
void method1();
String method2(String X);
}

Class A1 implements A
{
@Override
public void method1(){}
@Override
public String method2(String X) { return x; }
}
Si la classe qui implémente l'interface ne déclare pas toutes les méthodes de l'interface, le code ne s'exécutera pas et générera une erreur : « erreur : A1 n'est pas abstraite et ne remplace pas une méthode abstraite dans A1. " (erreur : A1 n'est pas abstrait et ne remplace pas une méthode abstraite dans A1). Avant JDK 8, les interfaces ne pouvaient pas définir d'implémentations, mais désormais des implémentations par défaut peuvent être ajoutées pour les méthodes d'interface. Nous pouvons également définir des méthodes statiques et par défaut, qui peut appeler sans objet dans l'interface Les interfaces sont principalement utilisées pour obtenir un héritage multiple et un couplage lâche dans le code.Maintenant que nous avons une compréhension claire des interfaces, voyons ce qu'est une interface fonctionnelle et comment elle fonctionne.

Qu'est-ce qu'une interface fonctionnelle ?

L'interface fonctionnelle est également connue sous le nom d'interface SAM (Single Abstract Method). Comme son nom l’indique, il ne peut avoir qu’une seule méthode abstraite. Une interface fonctionnelle peut avoir plusieurs méthodes statiques et par défaut avec une implémentation, ainsi qu'une méthode abstraite supplémentaire. Pour marquer une interface comme fonctionnelle, l' annotation @FunctionalInterface est utilisée . Ceci est nécessaire pour éviter de déclarer par erreur des méthodes supplémentaires. Ce qui rend l'interface fonctionnelle si populaire, c'est la possibilité d'utiliser des expressions lambda pour créer des interfaces sans utiliser d'implémentations de classes anonymes et lourdes. L'utilisation du mot-clé abstract dans les interfaces fonctionnelles est facultative car les méthodes définies au sein d'une interface sont abstraites par défaut.

Que sont les expressions lambda ?

Une expression lambda est une méthode sans nom ou anonyme qui ne s'exécute pas d'elle-même, mais est utilisée pour implémenter certaines méthodes d'une interface fonctionnelle. Il est défini comme suit :
(parameter list) -> lambda body
L'opérateur fléché ( -> ) que vous voyez dans le code est connu sous le nom d'opérateur lambda. Par exemple, si nous avons la méthode suivante :
double getGoldenRatioValue() {
return 1.61803;
}
En utilisant une expression lambda, nous pouvons l'écrire comme ceci :
() -> 1.61803
Comme vous pouvez le voir, la méthode de la fonction lambda n'a pas de paramètres, donc le côté gauche de l'instruction est vide. Puisque le côté droit détermine l’action, dans cet exemple, il renverra la valeur du nombre d’or : 1,61803. Avant Java 8, l'implémentation d'interfaces ou la création d'objets de classe internes était cruciale, mais avec Java 8, il ne nous reste plus qu'à attribuer des expressions lambda aux interfaces fonctionnelles.

Exemples d'interfaces fonctionnelles

Pour créer des interfaces fonctionnelles, vous pouvez soit utiliser l' annotation @FunctionalInterface , soit utiliser les interfaces fonctionnelles prédéfinies de Java.

Exemple 1

  • Tout d'abord, nous allons marquer @FunctionalInterface et créer une interface appelée MyInterface qui est appelée par la méthode abstraite getGoldenRationValue() .
  • Ensuite, nous créerons une classe publique main pour exécuter la méthode.
  • Pour utiliser une expression lambda dans une interface fonctionnelle, nous déclarerons une référence à MyInterfaceDemo puis attribuerons l'expression lambda à cette référence.
  • Enfin, nous imprimerons la valeur du nombre d’or à l’aide de l’interface de référence.
import java.lang.FunctionalInterface;

// Creation и маркировка функционального интерфейса
@FunctionalInterface

interface MyInterface {
// Это абстрактный метод
double getGoldenRatioValue();
}

public class Main {
public static void main( String[] args ) {

//декларируем ссылку на функциональный интерфейс
MyInterface ref;
//используем Lambda Expression
ref = () -> 1.61803;

System.out.println("Value of Golden Ratio = " + ref.getGoldenRatioValue());
}
}
Conclusion:
Valeur du nombre d'or = 1,61803

Exemple 2

  • Dans cet exemple, nous allons utiliser l'interface de fonction prédéfinie ToDoubleFunction , qui prend un argument T et renvoie un double en sortie.
  • ToDoubleFuntion contient une méthode abstraite appelée applyasDouble() .
  • Enfin, nous imprimons toute la longueur du message, espaces compris.
import java.util.function.ToDoubleFunction;
public class MyInterface2 {

public static void main(String[] args) {

ToDoubleFunction<String> length = x -> x.length();

System.out.println(length.applyAsDouble("This is an example of predefined functional interface."));
}
}
Conclusion:
54,0

Liste des interfaces fonctionnelles préinstallées

Maintenant que nous savons comment définir des interfaces fonctionnelles, voyons combien il existe d'interfaces fonctionnelles prédéfinies (intégrées). Il existe 4 principaux types d'interfaces fonctionnelles qui peuvent être implémentées dans différentes situations : Consumer , Predicate , Function et Supplier . Parmi ces quatre interfaces, Consumer , Function et Predicate ont des interfaces de fonction supplémentaires. Voici une liste de toutes les interfaces intégrées ou prédéfinies en Java. Note. T, U et R mentionnés dans le tableau ci-dessous représentent respectivement le type du premier argument (T), du deuxième argument (U) et du résultat (R) de l'opération.
Interface Taper
Exécutable
BiConsommateur (T, U) T, U →
BiFonction(T, U, R) T, U → R
Opérateur Binaire T, T <→ R
BiPrédicat<T, U> T, U → booléen
BooléenFournisseur → booléen
Consommateur T →
Opérateur DoubleBinary doubler, doubler → doubler
DoubleConsommateur doubler →
DoubleFonction doubler → R
DoublePrédicat double → booléen
DoubleFournisseur booléen →
DoubleToIntFunction double → entier
DoubleToLongFonction double → long
Opérateur DoubleUnaire doubler → doubler
Fonction<T, R> T → R
Opérateur IntBinaire entier → entier
IntConsommateur entier →
IntFonction entier → R
IntPrédicat int → booléen
Fournisseur international → entier
IntVersDoubleFonction entier → double
Fonction IntVersLong entier → long
Opérateur IntUnaire entier → entier
Opérateur LongBinary long, long → long
Consommateur long longue →
Fonction longue longue → R
Prédicat Long longue →
Fournisseur long → long
Fonction LongVersDouble long → double
Fonction LongVersInt long → entier
Opérateur LongUnaire long → long
ObjDoubleConsumer T, double →
ObjIntConsommateur T, entier →
ObjLongConsommateur T, long →
Prédicat T → booléen
Fournisseur → T
ÀDoubleBiFonction<T, U> T, U → double
ÀDoubleFonction T → double
ToIntBiFunction<T, U> T, U → int
ToIntFunction T → entier
ToLongBiFunction<T, U> T, U → long
ToLongFonction T → long
Opérateur unaire T → T

Résumons-le

Quelques points clés à retenir de cet article :
  • L'interface fonctionne comme un mécanisme d'abstraction.
  • Une interface fonctionnelle peut avoir plusieurs méthodes statiques et par défaut avec une implémentation, ainsi qu'une méthode abstraite supplémentaire.
  • Les méthodes définies dans une interface fonctionnelle sont abstraites par défaut, l'utilisation du mot-clé abstract n'est donc plus nécessaire.
  • Une expression lambda est une méthode anonyme qui ne s'exécute pas d'elle-même, mais sert à implémenter certaines méthodes d'une interface fonctionnelle.
  • Pour créer des interfaces fonctionnelles, vous pouvez soit utiliser l' annotation @FunctionalInterface , soit utiliser les interfaces fonctionnelles prédéfinies de Java.
Commentaires
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION