[Java] Introduction à l'expression lambda

introduction

Pour exécuter un thread en Java, utilisez une sous-classe qui hérite de la classe Thread, et Il existe une méthode utilisant une sous-classe qui implémente l'interface Runnable. Cette fois, ce dernier est pris comme exemple pour une brève explication de l'expression lambda.

Function.java


public class Function implements Runnable{
	@Override
	public void run() {
		//Que traiter dans le fil
		System.out.println("hello!");
	}
}

Main.java


public class Main {
	public static void main(String[] args) {
		Thread thread = new Thread(new Function());
		thread.start();
		System.out.println("finish!");
	}
}

Je pense que la sortie ressemblera à ceci.

finish!
hello!

Quelle est la relation entre la classe Thread et l'interface Runnable? La conception du modèle de stratégie du modèle de conception du GoF est utilisée. En gros, le modèle de stratégie est conçu pour «réaliser un algorithme remplaçable». La classe qui en était à l'origine est en charge du flux global de traitement, Divisons-le en classes qui sont en charge d'algorithmes spécifiques. En utilisant le modèle de stratégie, avec l'utilisateur (classe Thread) Le côté à utiliser (la classe qui réalise l'interface Runnable) Puisqu'il n'a pas à être directement lié, il est possible de réaliser un algorithme qui peut être remplacé plus tard. (Pour ceux qui veulent en savoir plus sur les modèles de stratégie, voir ici) UML2.png Cependant, la classe qui réalise l'interface est compliquée (classe FunctionHard dans le diagramme UML). Il y a quelque chose comme une classe qui nécessite un code simple (classe FunctionEasy dans le diagramme UML).

Nouvelles classes une par une, même avec du code simple N'est-ce pas ennuyeux d'avoir à définir? à propos de ça.

Effet de style Lambda

Afin de résoudre le problème présenté dans l'introduction, nous utiliserons l'expression lambda introduite à partir de Java SE 8. Le code suivant est remplacé par une expression lambda au lieu de créer une classe FunctionEasy.

Lambda.java


public class Lambda {
	public static void main(String[] args) {
		Runnable r = () -> System.out.println("hello!");
		Thread thread = new Thread(r);
		thread.start();
		System.out.println("finish!");
	}
}

Vous n'avez besoin que d'une seule ligne comme celle-ci. Rafraîchissant! Les expressions Lambda sont "lors de l'instanciation d'une interface fonctionnelle Vous pouvez le considérer comme «une notation qui ne nécessite pas d'écriture compliquée».

Une interface qui n'a qu'une seule méthode à implémenter est appelée "interface fonctionnelle" Elle est également appelée "interface SAM (Single Abstarct Method)".

Comme vous pouvez le voir sur SAM, il n'a qu'une seule méthode abstraite, donc Quelle méthode est implémentée par l'expression lambda? Qu'en est-il des arguments et des valeurs de retour? L'inférence est possible. Il n'est pas nécessaire de décider le nom de la méthode un par un. Le polymorphisme peut être réalisé sans préparer une classe qui réalise l'interface.

Classe anonyme et expression lambda

Avant Java8, il était réalisé par une classe anonyme. Les classes anonymes sont parfois appelées classes anonymes.


		Runnable r = new Runnable() {
			@Override
			public void run() {
				System.out.println("hello!");
			}
		}

C'est long et illisible.

Les expressions Lambda sont apparues dans Java 8 et il est devenu plus facile de les écrire.

		Runnable r = () -> {
			System.out.println("hello!");
		}

La déclaration d'expression lambda se compose de la déclaration de variable d'argument et du bloc de traitement comme indiqué ci-dessous.

     (argument) -> {En traitement; };

"->" Est appelé un opérateur de flèche.

Abréviation Lambda

Certaines expressions lambda peuvent être omises. Suivons le prototype suivant à titre d'exemple.

prototype



		Sample sample = (String a) -> { System.out.println(a);};

Abréviation notation 1

Si l'argument est ** uniquement lorsqu'il y en a un **, les parenthèses "()" peuvent être omises. En outre, le type de l'argument peut être déduit, de sorte qu'il peut être omis.

Abréviation notation 1


		Sample sample = a -> { System.out.println(a);};

Abréviation notation 2

De même, si le corps de la méthode est une ligne, la parenthèse du milieu "{}" et le point-virgule ";" à la fin de la phrase peuvent être omis. Dans le cas d'une instruction return, return peut également être omis.

Abréviation notation 2


		Sample sample = a -> System.out.println(a);

Notation d'abréviation 3

De plus, si l'argument peut être déduit, l'appel de la méthode Nom de la classe :: Nom de la méthode Nom de l'objet :: Nom de la méthode Il peut être omis comme ça.

Notation d'abréviation 3


		Sample sample = System.out::println;

Portée de la variable d'expression Lambda

Note 1

** Une variable portant le même nom que la variable locale déclarée dans la méthode ne peut pas être utilisée comme nom d'argument de l'expression lambda. ** ** Ce qui suit entraînera une erreur de compilation.

public class Sample {
	public static void main(String[] args) {
		String a = "sample";
		Function f = a -> System.out.println(a); //Erreur
		//Abréviation
	}
}

Comme le nom de variable a a déjà été déclaré en tant que variable locale, il ne peut pas être utilisé comme nom d'argument pour une expression lambda.

Note 2

** Pour accéder à une variable locale déclarée en dehors de l'expression lambda à partir de l'expression lambda, la variable locale doit être finale. Si le modificateur final n'est pas joint, il doit être final pratique. ** **

Vous pouvez accéder aux variables locales de la méthode qui entoure l'expression à partir de l'expression lambda. (Si vous y réfléchissez avant la conversion en expression lambda, c'est comme ça.) Vous pouvez accéder aux variables locales de la méthode qui déclare l'expression à partir de l'expression lambda comme suit:

«Substantiellement définitive» signifie une variable qui ne change pas, même si elle n'est pas qualifiée de manière définitive. Si vous modifiez la valeur d'une variable locale dans une expression lambda comme indiqué ci-dessous, une erreur de compilation se produit.

public class Sample {
	public static void main(String[] args) {
		String a = "sample";
		Function f = () -> {
			a = "change"; //Erreur
			System.out.println(a);
		};
		//Abréviation
	}
}

Package java.util.function et API de collecte

Les interfaces fonctionnelles fréquemment utilisées se trouvent dans le package java.util.function. En particulier, les cinq interfaces fonctionnelles suivantes sont célèbres.

Interface fonctionnelle Méthode argument Valeur de retour La description
Consumer<T> void accept(T) Oui Aucun "Consommateur" qui ne renvoie pas de valeur
Supplier<T> T get() Aucun Oui "Fournisseur" renvoyant une valeur
Predicate<T> boolean test(T) Oui Oui "Affirmation" qui renvoie une valeur booléenne
Function<T, R> R apply(T) Oui Oui "Traitement" qui reçoit un argument et renvoie le résultat du type spécifié
UnaryOperator<T> T apply(T t) Il y en a deux Oui "Opération" qui renvoie le résultat du calcul

L'API Collection a de nombreuses méthodes par défaut pour manipuler List et Map.

Par exemple, java.util.List a une méthode appelée * removeIf (Predicate filter) * qui supprime les éléments qui correspondent au filtre. Si vous utilisez l'expression lambda, vous n'avez besoin que d'une seule ligne.

RemoveIf.java


import java.util.ArrayList;
import java.util.Arrays;

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

		ArrayList<String> list = new ArrayList<String>(Arrays.asList("aaaa", "bbb", "cc"));

		list.removeIf(v -> v.length() > 3);

		System.out.println(list); //résultat: [bbb, cc]
	}
}

Il existe de nombreuses autres méthodes qui vous permettent de spécifier une expression lambda. Examinons par vous-même et implémentons-le avec une expression lambda pour nous y habituer.

Conclusion

Il existe de nombreuses applications WEB dont le côté serveur s'exécute sous Java 8. Par conséquent, je pense que l'expression lambda et l'API Stream sont des connaissances inévitables lorsque vous utilisez Java maintenant. Néanmoins, il semble que certaines choses ne sont pas enseignées dans la formation des nouveaux arrivants Java. J'ai essayé de le résumer le plus facilement possible pour les nouveaux arrivants. Je suis désolé s'il y a une partie difficile à comprendre.

La prochaine fois, je résumerai l'introduction à l'API Stream dans la semaine prochaine.

(Mis à jour le 22 décembre 2019) Sequel Something → [Java] Introduction to Stream API

Recommended Posts

[Java] Introduction à l'expression lambda
[Introduction à Java] À propos des expressions lambda
[Java] Introduction à Java
Introduction à Java
Comment utiliser les expressions Java lambda
J'ai essayé de résumer les expressions Java lambda
Comprendre les expressions lambda Java 8
À propos des expressions Java lambda
Introduction au style lambda
Expliquer les expressions lambda Java 8
Introduction à la commande java
[Java] Résumé de la façon d'omettre les expressions lambda
[Java] Introduction à l'API Stream
[Introduction aux jeux Janken (comme)] Java
[Java Silver] Résumé des points liés aux expressions lambda
[Java] Introduction
Expression lambda Java apprise avec Comparator
[Introduction à Java] À propos de l'API Stream
Introduction à la programmation fonctionnelle (Java, Javascript)
Introduction initiale à Mac (ingénieur Java)
L'origine des expressions Java lambda
De nos jours, les expressions Java Lambda et l'API de flux
Introduction aux algorithmes avec java-Search (recherche prioritaire en profondeur)
[Introduction à Java] Comment écrire un programme Java
Introduction à web3j
Introduction à Micronaut 1 ~ Introduction ~
Introduction à la migration
Bonjour Java Lambda
[Java] Expression Lambda
Sortie du livre "Introduction à Java"
Introduction à la surveillance à partir de Java Touching Prometheus
[Introduction à Java] À propos des déclarations et des types de variables
Facile à parcourir avec les expressions régulières Java
Introduction à Doma
Expression lambda Java
Introduction aux algorithmes avec java --Search (recherche de priorité de largeur)
[Introduction à Java] À propos de la conversion de type (distribution, promotion)
Introduction aux algorithmes avec java --Search (bit full search)
Ingénieur en route vers Java Partie 1 Introduction et construction de l'environnement
Comment utiliser le framework Java avec AWS Lambda! ??
[Mensuel 2017/04] Introduction à groovy !! ~ Comparaison de grammaire / spécification Java ~
Comment utiliser l'API Java avec des expressions lambda
Java 8 pour démarrer maintenant ~ for Each et expression lambda ~
Premiers pas avec Groovy pour les ingénieurs Java gênants
[Introduction à Java] Bases de l'arithmétique Java (pour les débutants)
Java Performance Chapitre 1 Introduction
Introduction aux fichiers JAR
Changements de Java 8 à Java 11
Somme de Java_1 à 100
Introduction à Ratpack (8) - Session
expression 1 de la table lambda neutre java
Introduction à Ratpack (6) - Promesse
Quarkus enregistre Java Lambda! ??
Introduction à Ratpack (9) --Thymeleaf
[Java] Connectez-vous à MySQL
Variations d'expressions lambda Java
Introduction à PlayFramework 2.7 ① Présentation