Maison  >  Article  >  Java  >  Compréhension approfondie des expressions Lambda et des interfaces fonctionnelles

Compréhension approfondie des expressions Lambda et des interfaces fonctionnelles

青灯夜游
青灯夜游avant
2019-11-25 15:44:022116parcourir

Java8 est considérée comme la version la plus modifiée de l'histoire de Java. Il contient de nombreuses nouvelles fonctionnalités importantes, dont la principale est l'ajout d'expressions Lambda et de l'API Stream. Les deux peuvent également être utilisés ensemble. [Apprentissage recommandé : Tutoriel vidéo Java]

Compréhension approfondie des expressions Lambda et des interfaces fonctionnelles

Regardons d'abord qu'est-ce qu'une expression Lambda.

Expression Lambda, l'explication sur Wikipédia est un opérateur utilisé pour représenter des fonctions anonymes et des fermetures. J'ai toujours l'impression que c'est très abstrait après avoir vu cette explication

public class SwingTest {
    public static void main(String[] args) {
        JFrame jFrame = new JFrame("My JFrame");
        JButton jButton = new JButton("My JButton");

        jButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {                
                System.out.println("Button Pressed!");
            } 
        }); 
        
        jFrame.add(jButton); jFrame.pack(); 
        jFrame.setVisible(true); 
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    }
}
<.>Il s'agit d'un code dans la programmation Swing qui lie un événement d'écoute à Button. Lorsque vous cliquez sur le bouton, "Button Pressed!" sera affiché sur la console. Ici, une instance d'une classe interne anonyme est créée pour se lier à l'auditeur, ce qui était également une forme d'organisation de code plus conventionnelle dans le passé. Mais si nous y regardons de plus près, nous constaterons qu'en fait, ce sur quoi nous nous concentrons réellement est un paramètre de type ActionEvent e et l'instruction System.out.println("Button Pressed!");

Si vous remplacez le code qui crée une instance d'interface à l'aide d'une classe interne anonyme dans le programme précédent par une expression Lambda, le code est le suivant
classe publique SwingTest {

public static void main(String[] args) {
    JFrame jFrame = new JFrame("My JFrame");
    JButton jButton = new JButton("My JButton");

    jButton.addActionListener(e -> System.out.println("Button Pressed!"));

    jFrame.add(jButton);
    jFrame.pack();
    jFrame.setVisible(true);
    jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

Focus sur la partie médiane Le changement de code peut être implémenté sur une seule ligne à partir des 6 lignes de code d'origine. Il s'agit d'une forme simple d'expression Lambda.
On peut voir que la syntaxe de l'expression Lambda est
(param1,param2,param3) -> {

//todo
>

Le programme de type des paramètres ici peut être déduit en fonction sur le contexte, mais ce n'est pas le cas. Tous les types ne peuvent pas être déduits. À ce stade, nous devons déclarer explicitement le type du paramètre. Lorsqu'il n'y a qu'un seul paramètre, les parenthèses peuvent être omises. Lorsque la section todo ne contient qu’une seule ligne de code, les accolades extérieures peuvent être omises. Comme notre exemple ci-dessus

En plus du code concis, l'expression Lambda nous a-t-elle apporté des changements ?

Rappelons qu'en Java, on ne peut pas passer une fonction en paramètre à une méthode, ni déclarer que la valeur de retour est une méthode d'une fonction. Avant Java8, la réponse était oui.

Ainsi, dans l'exemple ci-dessus, nous pouvons réellement transmettre un morceau de code logique en tant que paramètre à l'auditeur, indiquant à l'auditeur que vous pouvez le faire lorsque l'événement est déclenché, au lieu d'utiliser une classe interne anonyme. comme paramètre. C'est aussi une autre nouveauté apportée par Java8 : la programmation fonctionnelle.

Il existe de nombreux langages qui prennent en charge la programmation fonctionnelle. En JavaScript, il est très courant de passer une fonction en paramètre ou la valeur de retour est une fonction. JavaScript est un langage fonctionnel très courant.

Lambda ajoute des fonctionnalités de programmation fonctionnelle manquantes à Java, nous permettant de traiter les fonctions comme des citoyens de première classe.

Dans les langages de programmation fonctionnels, le type d'expression Lambda est une fonction.

En Java, les expressions Lambda sont des objets, et elles doivent être attachées à un type d'objet spécial - Functional Interface (Functional Interface) .

Regardons ensuite la définition de l'interface fonctionnelle :

S'il y a une et une seule méthode abstraite dans une interface (les méthodes de la classe Object ne sont pas incluses), alors cette interface Elle peut être considérée comme une interface fonctionnelle.

@FunctionalInterface
public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run();
}
Jetons un coup d'œil à la déclaration de l'interface Runnable. Après Java 8, l'interface Runnable a une annotation FunctionalInterface supplémentaire, indiquant que l'interface est une interface fonctionnelle. Mais si nous n'ajoutons pas l'annotation FunctionalInterface, s'il y a et n'y a qu'une seule méthode abstraite dans l'interface, le compilateur traitera l'interface comme une interface fonctionnelle.

@FunctionalInterface
public interface MyInterface {
    void test();
    String toString();
}
MyInterface C'est également une interface fonctionnelle, car toString() est une méthode de la classe Object. Elle est simplement remplacée ici et n'augmentera pas le nombre de méthodes abstraites dans l'interface.

(Une mention supplémentaire ici est que dans Java 8, les méthodes de l'interface peuvent non seulement avoir des méthodes abstraites, mais peuvent également avoir des méthodes concrètes implémentées, qui sont appelées méthodes par défaut. Cette partie sera présentée en détail plus tard. )
Puisqu'en Java, les expressions Lambda sont des objets. Alors quel est le type de cet objet ? Revoyons à nouveau le programme SwingTest. Ici, une instance d'interface ActionListener est créée sous la forme d'une classe interne anonyme

jButton.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent e) {                
        System.out.println("Button Pressed!");
    } 
});
Améliorée à l'aide d'expressions Lambda

jButton.addActionListener(e -> System.out.println("Button Pressed!"));
Autrement dit, nous utilisons des expressions Lambda pour créer an Un exemple de l'interface ActionListener. Regardons la définition de l'interface ActionListener.

public interface ActionListener extends EventListener {
    /**
     * Invoked when an action occurs.
     */
    public void actionPerformed(ActionEvent e);
}
n'a qu'une seule méthode abstraite Bien que l'annotation FunctionalInterface ne soit pas ajoutée, elle est toujours conforme à la définition d'une interface fonctionnelle. Le compilateur considérera qu'il s'agit d'une interface fonctionnelle.

Ainsi, en utilisant des expressions Lambda, vous pouvez créer des instances d'interfaces fonctionnelles. Autrement dit, l'expression Lambda renvoie un type d'interface fonctionnelle.

En fait, il existe trois façons de créer des instances d'interface fonctionnelle (se référer à l'annotation FunctionalInterface) :

1 Expression Lambda

Référence de la méthode (introduction au chapitre suivant). )

3. Référence de la méthode constructeur (introduction du chapitre suivant)

Résumé : Dans cet article, nous avons ouvert la porte à l'apprentissage de Java 8, appris ce que sont les expressions lambda, compris quelle est la définition des interfaces fonctionnelles et utilisé plusieurs exemples pour démontrer la commodité des expressions lambda.

Pour plus d'articles connexes, veuillez consulter : Introduction à l'apprentissage 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:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer