Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use lambdas for interfaces with multiple methods?

Is there a way to use lambdas if the target class has more than one interface methods? Or do you just have to use an anonymous inner class in that case?

like image 677
sth8119 Avatar asked Apr 14 '14 00:04

sth8119


People also ask

Can lambda expressions be used for all interfaces?

From Java 8 onwards, lambda expressions can be used to represent the instance of a functional interface. A functional interface can have any number of default methods.

Can functional interface have multiple methods?

An Interface that contains exactly one abstract method is known as functional interface. It can have any number of default, static methods but can contain only one abstract method. It can also declare methods of object class. Functional Interface is also known as Single Abstract Method Interfaces or SAM Interfaces.

CAN interface have 2 abstract methods?

Interface can have only abstract methods. Since Java 8, it can have default and static methods also. 2) Abstract class doesn't support multiple inheritance.

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.


2 Answers

It is not possible to directly create a multi-method object with a lambda.

But, you can use a work-around to solve the problem in a pretty neat way:

Use a util method that takes a number of single-method objects as arguments, and returns a multi-method object, into which the single-method objects have been packed.

Example:

interface MultiMethodInterface {
    void method1();
    String method2(String arg);
}

public static void example() {
    // One lambda for each method, they are packed into a 
    // MultiMethodInterface object by the multiMethodInterface method
    MultiMethodInterface i1 = createMultiMethodObject(
            () -> System.out.println("method1"),
            arg -> "method2: " + arg);

    // Sometimes only one of the methods is used, a specialized wrapper
    // can be used if that is common
    MultiMethodInterface i2 = 
            createMethod1Wrapper(() -> System.out.println("method1"));
}

public static MultiMethodInterface createMultiMethodObject(
        Runnable methodAction1,
        Function<String, String> methodAction2)
{
    return new MultiMethodInterface() {
        @Override
        public void method1() {
            methodAction1.run();
        }
        @Override
        public String method2(String arg) {
            return methodAction2.apply(arg);
        }
    };
}

public static MultiMethodInterface createMethod1Wrapper(Runnable methodAction1) {
    return createMultiMethodObject(methodAction1, arg -> "");
}

The resulting code is at least a bit shorter and prettier than to create a anonymous class. At least if the method implementations are short, and/or only one of the methods needs to be implemented.

This technique is used for example in the SWT toolkit, to create listener objects.

like image 137
Lii Avatar answered Oct 24 '22 09:10

Lii


No, there isn't. If I understood your question correctly you'd want to use lambdas for interfaces with more than one abstract method. In that case the answer is negative:

A functional interface is any interface that contains only one abstract method. (A functional interface may contain one or more default methods or static methods.) Because a functional interface contains only one abstract method, you can omit the name of that method when you implement it. To do this, instead of using an anonymous class expression, you use a lambda expression [...]

Read it up there: http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html

like image 26
VH-NZZ Avatar answered Oct 24 '22 08:10

VH-NZZ