J'ai Java SE8 Gold, et maintenant je peux utiliser l'interface fonctionnelle, l'expression lambda et l'API Stream qui ont occupé la plupart des questions, mais qu'est-ce que c'est après tout? C'était dans un état.
Par conséquent, j'ai décidé de résumer pourquoi la programmation fonctionnelle a été introduite en premier lieu et comment est née l'idée d'interfaces fonctionnelles et d'expressions lambda. (~~ Résumez avant de passer l'examen ~~)
Tout à coup, jetez un œil au code ci-dessous.
public static void findMatsumoto(List<String> names) {
boolean found = false;
for (String name : names) {
if (name.equals("Matsumoto")) {
found = true;
break;
}
}
if (found)
System.out.println("Found Matsumoto");
else
System.out.println("Sorry, Matsumoto not found");
}
C'est une méthode très simple. La liste de noms passée en argument est bouclée élément par élément pour vérifier si elle correspond à Matsumoto. S'il y a un élément qui correspond à Matsumoto, définissez la variable locale trouvée préparée à l'avance sur true et quittez la boucle. Enfin, si trouvé est vrai, "found Matsumoto" est affiché, et si trouvé est faux, "Désolé, Matsumoto introuvable" est affiché.
Comme mentionné ci-dessus, cette méthode est écrite dans ce que l'on appelle la "** programmation pédagogique **" qui définit toutes les étapes de répétition de chaque élément, de comparaison des valeurs, de définition des indicateurs et de sortie de la boucle. Je vais.
Si vous essayez de décrire la méthode de ↑ par programmation fonctionnelle, ce sera comme suit.
public static void findMatsumoto(List<String> names) {
if (names.contains("Matsumoto"))
System.out.println("Found Matsumoto");
else
System.out.println("Sorry, Matsumoto not found");
}
C'est beaucoup plus propre que la programmation pédagogique, n'est-ce pas? En particulier, le type de fonction ne décrit pas le traitement en boucle. La méthode contains s'occupe de tout, et le développeur n'a rien à voir avec la façon dont c'est fait. Cependant, vous pouvez obtenir le résultat attendu avec juste cette description.
En d'autres termes, l'écriture en programmation fonctionnelle peut aboutir à un ** code concis et facile à comprendre ** par rapport à la programmation impérative.
★ Références [1] [Raccourci vers la transition vers la programmation fonctionnelle - Introduction de méthodes fonctionnelles dans les programmes Java avec une façon de penser déclarative-](https://www.ibm.com/developerworks/jp/java/library/j- java8idioms1 / index.html)
En plus de rendre le code concis et facile à comprendre, la programmation fonctionnelle présente de nombreux avantages.
En programmation fonctionnelle, les fonctions ont les propriétés suivantes. ** ● Renvoie toujours le même résultat pour la valeur saisie ** ** ● L'évaluation des fonctions n'a aucun effet sur les autres **
Les méthodes suivantes peuvent être appelées des fonctions.
public int add(int x, int y) {
return x + y;
}
Il renvoie toujours le même résultat pour les entrées (x et y), et l'évaluation ici n'a pas d'autre effet.
D'autre part, les méthodes suivantes peuvent-elles être appelées fonctions?
public int add(int y) {
return x += y; //x est une variable définie en dehors de la méthode
}
Cette méthode ne renvoie pas toujours le même résultat pour l'entrée y. (Dépend de la variable externe x.) Il affecte également la variable externe x. D'après ce qui précède, cette méthode ne peut pas être appelée une fonction.
En raison des propriétés ci-dessus, les avantages suivants peuvent être pris en compte en utilisant la fonction. ** 1. Facile à tester ** Vous n'avez besoin de considérer qu'un seul scénario de test, car le même résultat sera toujours renvoyé pour la valeur que vous entrez.
** 2. Hautement sûr ** Comme l'évaluation par la fonction n'a aucune influence sur les autres, elle est très sûre sans changements inattendus.
** 3. Rationalisez le traitement parallèle ** Il convient au traitement parallèle car les fonctions ne dépendent pas les unes des autres. Ces dernières années, l'amélioration des performances d'un seul cœur s'est ralentie et l'architecture du processeur a tendance à être multicœur avec plus de cœurs. On s'attend à ce que l'utilisation des fonctions corresponde à cette tendance vers le multicœur. En d'autres termes, il est possible d'améliorer l'efficacité du traitement parallèle et d'améliorer la vitesse de traitement.
De plus, il existe deux propriétés notables de la programmation fonctionnelle: ** ● Vous pouvez passer une fonction comme argument d'une fonction ** ** ● Vous pouvez transmettre la fonction comme valeur de retour de la fonction **
Je voudrais montrer un exemple concret utilisant "** Haskell **" qui est célèbre comme langage de programmation fonctionnel.
Ce qui suit est un programme qui génère la valeur totale des éléments du tableau.
haskell
ary = [ 1, 3, 5, 7, 9 ]
main = print $ foldl (+) 0 ary
La fonction (+) est passée comme premier argument d'une fonction appelée foldl. Renvoie la valeur totale des éléments du tableau ary passé dans le 3ème argument, avec 0 comme valeur initiale dans le 2ème argument. Vous pouvez voir qu'il est écrit de manière très concise.
Si vous essayez de faire la même chose en Java,
Java
public static int addAll(int[] ary) {
int total = 0;
for (int i : ary) {
total += i;
}
return total;
}
public static void main(String[] args) {
int[] ary = { 1, 3, 5, 7, 9 };
System.out.println(addAll(ary));
}
Ce sera. J'écris un processus en boucle, donc le code est un peu long.
Si vous utilisez la programmation fonctionnelle, vous pouvez décrire le processus d'affichage des éléments d'un tableau sur la console en ** une seule ligne **, de sorte que la différence dans la quantité de description est évidente.
****** Jusqu'à présent, je n'ai couvert que les avantages de la programmation fonctionnelle, mais je ne pense pas aveuglément que la programmation fonctionnelle est la meilleure !!! ** Pour clarifier le contexte ** Seules les prestations sont prises en compte. La supériorité et l'infériorité de la programmation fonctionnelle, de la programmation pédagogique et de la programmation procédurale sortent du cadre de cet article et ne seront pas discutées. (Parfois, je ne suis pas si familier avec la programmation fonctionnelle que je peux en discuter moi-même.)
★ Références [2] Allons-y avec la programmation fonctionnelle ~ L'entrée de l'entrée fonctionnelle que tout le monde aime de Java [3] Connaissons la puissance de la programmation fonctionnelle - Partie 2
Je l'ai écrit depuis longtemps jusqu'à présent, mais pour résumer brièvement, la programmation fonctionnelle présente de nombreux avantages, et introduisons-la à Java! C'est devenu. Cependant, bien que cela ait de grands mérites, ce n'était pas simple en raison des défis.
Notez que, comme vous pouvez le voir d'après la nature des fonctions en programmation fonctionnelle, "Vous pouvez passer une fonction à l'argument d'une fonction", "fonction en programmation fonctionnelle" = "méthode".
Pour élaborer un peu plus, la programmation fonctionnelle traite une fonction comme un objet de première classe, vous pouvez donc passer une fonction en tant qu'argument de fonction, mais comme un objet de première classe en Java est une classe, ** une méthode est utilisée comme argument de méthode. Il ne peut pas être adopté **.
Comme mentionné précédemment, Java ne vous permet pas de transmettre une méthode en tant qu'argument de méthode. Cependant, s'il s'agit d'un objet (instance), vous pouvez le passer en argument!
Alors, j'ai créé un ** objet de type fonction ! Ensuite, " interface fonctionnelle **" a été conçue.
C'est une "interface fonctionnelle" créée comme un objet de type fonction, mais sa définition est la suivante.
** ● Interface avec une seule méthode abstraite (interface SAM) **
Exemple spécifique d'interface fonctionnelle
@FunctionalInterface
public interface Example {
public int calc(int x); //Méthode abstraite (SAM)
static void say() { } //méthode statique
default void hello() { } //méthode par défaut
public String toString(); //Méthode publique de la classe Object
}
Ceci est une interface fonctionnelle!
** e? ** **
Où est-ce une fonction? Je pense que j'ai ressenti cela. Eh bien, c'est compréhensible en l'utilisant, alors écrivons un programme.
Lorsque vous passez un objet fonction (interface de type de fonction) comme argument d'une méthode, utilisez la notation "** classe interne anonyme **". Pour plus d'informations sur les classes internes anonymes, veuillez vous référer à la littérature [4].
//Interface fonctionnelle
@FunctionalInterface
public interface Calc {
public int add(int x, int y); //Méthode abstraite (SAM)
}
//Implémentation de la méthode d'impression avec Calc comme argument
private void print(int x, int y, Calc c) {
System.out.println(c.add(x, y));
}
//Appelez la méthode d'impression
print(3, 4, new Calc() {
@Override
public int add(int x, int y) {
return x + y;
}
});
//Résultat d'exécution 7
Comme décrit ci-dessus, en utilisant la classe interne anonyme, il est possible d'instancier l'interface fonctionnelle Calc, d'implémenter la méthode abstraite add et de la transmettre à l'argument de la méthode d'impression.
** e? ** **
La quantité de description n'est pas du tout petite et cela ne ressemble pas à une programmation fonctionnelle! !!
C'est vrai. C'est là que le "** style Lambda **" entre en jeu.
★ Références [4] Classe intérieure anonyme [5] Introduction à Java8 Lambda [6] Interfaces fonctionnelles - Apprenez à créer des interfaces fonctionnelles personnalisées et pourquoi vous devriez toujours utiliser des interfaces fonctionnelles intégrées lorsque cela est possible- /java/library/j-java8idioms7/index.html)
Une expression lambda est une notation qui simplifie l'instanciation d'une classe qui implémente une méthode abstraite d'une interface fonctionnelle (ce qui a été fait plus tôt dans la classe interne anonyme).
Voyons comment l'omettre concrètement. (1) Premièrement, il est évident d'après l'inférence de type du compilateur que le type de la variable qui peut être passé au troisième argument de la méthode d'impression est un objet de type Calc, donc "new Calc () {}" peut être omis.
(2) De plus, puisque l'interface Calc est une interface fonctionnelle, puisqu'il n'y a qu'une seule méthode abstraite, il est évident de la surcharger et de l'implémenter, donc "@ Override public int add" peut également être omis.
(3) Enfin, le type d'argument est également évident par inférence de type, il peut donc être omis, et si le bloc de méthode ({}) est omis, le mot-clé return peut également être omis (dans ce cas, return ne peut pas être décrit plutôt que omis). Sur la base de ce qui précède, l'appel ci-dessus à la méthode d'impression peut être réécrit comme suit.
//Appelez la méthode d'impression
print(3, 4, (x, y) -> x + y);
Oh, c'est vraiment court! Ce que nous faisons est le même que pour la classe interne anonyme, nous implémentons la méthode add add pour instancier la classe, mais la description du nouvel opérateur et des substitutions de méthode qui sont normalement requises pour l'instanciation est C'est abrégé, donc c'est très concis, et il semble que vous passiez une ** fonction (méthode) qui fait l'ajout directement à l'argument de la méthode **.
C'est vrai! !! En d'autres termes, ** le code écrit simplifié à l'aide d'expressions lambda ressemble à de la programmation fonctionnelle **!
Vous avez découvert que vous pouvez introduire la programmation fonctionnelle en utilisant une combinaison d'interfaces fonctionnelles et d'expressions lambda.
Et le package java.util.function de Java8 fournit une interface de type fonction à usage général, et le package java.util.stream est une API pour le traitement des données dans un format de pipeline, avec une interface de type fonction comme argument. Il existe de nombreuses méthodes à adopter. Bien sûr, vous pouvez également créer une interface fonctionnelle personnalisée.
Le programme suivant affiche les noms des hommes dans la liste des noms.
names.stream().filter(n -> n.getSex() == 0)
.map(n -> n.getName())
.forEach(System.out::println);
N'est-ce pas facile à lire et concis? De cette manière, une bonne combinaison d'interfaces fonctionnelles et d'expressions lambda, d'interfaces fonctionnelles intégrées et d'API Stream peut introduire la programmation fonctionnelle.
Je voudrais résumer le package java.util.function et l'API Stream dans un article séparé.
★ Références [7] [Collecte des problèmes de Thorough Strategy Java SE 8 Gold](https://www.amazon.co.jp/ Thorough Strategy-Java-Gold-Problem Collection-1Z0-809 / dp / 4295000035 / ref = sr_1_2? S = livres & ie = UTF8 & qid = 1538986245 & sr = 1-2 & mots-clés = java + or + se8) [8] Comprendre les expressions Java 8 Lambda
Comme la programmation fonctionnelle présente de nombreux avantages, j'aimerais également l'introduire dans Java. ↓ En préparant un objet (interface fonctionnelle) qui n'a qu'une seule classe abstraite au lieu d'une fonction et en simplifiant l'instanciation de classe à l'aide d'expressions lambda, nous avons pu introduire la programmation fonctionnelle dans Java! !!
Recommended Posts