Je suis liitFeet, un ingénieur côté serveur. Récemment, je me sens comme Coroutine WebFlux exclusivement avec kotlin et Spring Boot. Coroutine difficile ...
Cet article est le 7ème jour du calendrier de l'avent TeamLab Engineering.
Dans cet article, j'expliquerai l'origine des expressions Java lambda. Eh, maintenant? Il y a un sentiment comme ça, mais maintenant que je peux gérer des fonctions telles que go et kotlin comme des objets de première classe, j'ai pensé qu'il semble que j'utilise réellement le contenu de l'expression lambda sans savoir ce que c'est.
L'essentiel est que les expressions java lambda implémentent une interface avec une seule méthode pour créer une instance (nouvelle). Je ne pense pas que cette explication prête à confusion, je vais donc expliquer le processus jusqu'à l'expression lambda dans l'ordre, en utilisant un programme qui affiche le résultat du calcul d'une certaine expression à titre d'exemple.
Je pense que c'est plus facile à comprendre si vous savez que les expressions lambda sont faciles à lire pour les humains et les compilateurs tout en réduisant la quantité de description.
En outre, cet article décrit l'origine des expressions Java lambda, Veuillez noter que nous n'expliquerons pas l'expression lambda elle-même en détail (s'il n'y a qu'un seul argument, vous n'avez pas besoin d'écrire de parenthèses, d'interface fonctionnelle, etc.).
Le code source peut être trouvé sur GitHub.
Tout d'abord, je voudrais réaliser un programme qui affiche le résultat calculé en passant une classe normale. Le code source est le package normalClass. Il y a quatre sources ci-dessous.
Main.classe principale java
Display.java Class pour afficher le résultat du calcul
CalcuratorInterface.Interface définie pour le calcul Java
Display.java CalcuratorInterface
Tout d'abord, dans la classe Display, il reçoit la calculatrice en charge du calcul et la valeur (a, b) à calculer. Calculez et affichez la valeur de (a, b) avec la calculatrice.
public class Display {
public void showCalc(CalculatorInterface calculator, int a, int b) {
System.out.println(calculator.calc(a, b));
}
}
CalculatorInterface définit calc, une méthode qui effectue des calculs.
public interface CalculatorInterface {
int calc(int a, int b);
}
AddCalculator implémente CalculatorInterface et renvoie la somme des arguments (a, b).
public class AddCalculator implements CalculatorInterface {
@Override
public int calc(int a, int b) {
return a + b;
}
}
Dans la classe Main, le résultat du calcul est affiché en transmettant la valeur calculée à la classe Display en tant que `` calculatrice ''.
public class Main {
public static void main(String[] args) {
Display display = new Display();
CalculatorInterface calculator = new AddCalculator();
display.showCalc(calculator, 3, 5);
}
}
Je pense qu'il n'y a pas de problème particulier.
Ensuite, je voudrais utiliser la classe interne. Le code source est le package innerClass. CalcuratorInterface.java et Display.java sont inchangés.
Si vous utilisez la classe normale mentionnée ci-dessus, ne pensez-vous pas qu'il est gênant de créer un fichier de classe uniquement pour l'ajout qui n'est utilisé que pour la classe Main? Par conséquent, vous pouvez éliminer AddCalculator.java en définissant AddCalculator dans Main comme indiqué ci-dessous.
public class Main {
public static void main(String[] args) {
Display display = new Display();
//Définir la classe interne
class AddCalculator implements CalculatorInterface {
@Override
public int calc(int a, int b) {
return a + b;
}
}
CalculatorInterface calculator = new AddCalculator();
display.showCalc(calculator, 3, 5);
}
}
Ensuite, nous utiliserons la classe anonyme. Le code source est le package anonymousInnerClass. J'ai utilisé la classe interne et je n'ai pas eu à créer un fichier de classe, mais si je ne l'utilise qu'une fois ici, je n'ai pas besoin de nommer cette classe. Par conséquent, implémentons la classe sur place au moment de l'attribuer à la calculatrice.
public class Main {
public static void main(String[] args) {
Display display = new Display();
//Jetable une fois
CalculatorInterface calculator = new CalculatorInterface() {
@Override
public int calc(int a, int b) {
return a + b;
}
};
display.showCalc(calculator, 3, 5);
}
}
Ceci est une classe anonyme. Il ne peut pas être réutilisé, mais la quantité de description a progressivement diminué.
Enfin, passer des arguments à l'aide d'expressions lambda. Le code source est lambdaExpression Package. En utilisant une classe anonyme, j'ai pu omettre le nom de la classe et réduire la quantité de description. Cependant, si vous implémentez CalculatorInterface, il semble que le compilateur le fera pour vous sans écrire `` new CalculatorInterface () ''. En outre, s'il n'y a qu'une seule méthode, la méthode à implémenter est déterminée de manière unique. Le type de l'argument de méthode est également défini dans l'interface, et le compilateur peut déduire le type sans le déclarer.
Dans les expressions lambda, vous pouvez créer une instance en écrivant uniquement les méthodes requises pour l'implémentation.
public class Main {
public static void main(String[] args) {
Display display = new Display();
//Seul le traitement de la méthode à mettre en œuvre
CalculatorInterface calculator = (a, b) -> {
return a + b;
};
display.showCalc(calculator, 3, 5);
}
}
L'expression lambda est la partie suivante. Cette partie représente l'implémentation de la méthode calc de CalculatorInterface.
(a, b) -> {
return a + b;
};
(a, b)
Est un argument. Je ne prends pas la peine d'écrire l'argument de la méthode car le type est défini dans l'interface.
->
Voici la mise en œuvre de la méthode.a+b
Est de retour.
Qu'as-tu pensé. J'espère que vous pouvez comprendre la signification du premier énoncé "les expressions java lambda implémentent une interface avec une seule méthode et créent une instance (nouvelle)"!
C'est un aparté complet, mais ce serait bien si vous pouviez gérer la fonction comme un objet de première classe comme kotlin ... Les arguments sont faciles à comprendre ...
val calculator = {a: Int, b: Int -> a + b}
showCalc(calculator, 3, 5)
fun showCalc(calc: (Int, Int) -> Int, a: Int, b: Int) {
println(calc.invoke(a, b))
}
Recommended Posts