Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 Lambda Expressions - what about multiple methods in nested class

I'm reading about the new features at: http://www.javaworld.com/article/2078836/java-se/love-and-hate-for-java-8.html

I saw the example below:

Using Anonymous Class:

button.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent ae) {
        System.out.println("Action Detected");
    }
});

With Lambda:

button.addActionListener(e -> {
    System.out.println("Action Detected");
});

What would someone do with a MouseListener if they wanted to implement multiple methods within the anonymous class, e.g.:

public void mousePressed(MouseEvent e) {
    saySomething("Mouse pressed; # of clicks: "
               + e.getClickCount(), e);
}

public void mouseReleased(MouseEvent e) {
    saySomething("Mouse released; # of clicks: "
               + e.getClickCount(), e);
}

... and so on?

like image 989
Menelaos Avatar asked Feb 17 '14 15:02

Menelaos


People also ask

Can lambda function have multiple methods?

Since a lambda function can only provide the implementation for 1 method it is mandatory for the functional interface to have ONLY one abstract method.

Can we have multiple methods in functional interface?

A functional interface is an interface that contains only one abstract method. They can have only one functionality to exhibit.

Can lambda have multiple parameters Java?

The lambda expressions are easy and contain three parts like parameters (method arguments), arrow operator (->) and expressions (method body). The lambda expressions can be categorized into three types: no parameter lambda expressions, single parameter lambda expressions and multiple parameters lambda expressions.


2 Answers

From JLS 9.8

A functional interface is an interface that has just one abstract method, and thus represents a single function contract.

Lambdas require these functional interfaces so are restricted to their single method. Anonymous interfaces still need to be used for implementing multi-method interfaces.

addMouseListener(new MouseAdapter() {

    @Override
    public void mouseReleased(MouseEvent e) {
       ...
    }

    @Override
    public void mousePressed(MouseEvent e) {
      ...
    }
});
like image 88
Reimeus Avatar answered Oct 11 '22 16:10

Reimeus


You can use multi-method interfaces with lambdas by using helper interfaces. This works with such listener interfaces where the implementations of unwanted methods are trivial (i.e. we can just do what MouseAdapter offers too):

// note the absence of mouseClicked…
interface ClickedListener extends MouseListener
{
    @Override
    public default void mouseEntered(MouseEvent e) {}

    @Override
    public default void mouseExited(MouseEvent e) {}

    @Override
    public default void mousePressed(MouseEvent e) {}

    @Override
    public default void mouseReleased(MouseEvent e) {}
}

You need to define such a helper interface only once.

Now you can add a listener for click-events on a Component c like this:

c.addMouseListener((ClickedListener)(e)->System.out.println("Clicked !"));
like image 85
Holger Avatar answered Oct 11 '22 17:10

Holger