Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lambda for JavaFX Task

Tags:

java

javafx

The compiler gives me this error "Target Type of lambda expression must be an interface" for this code:

Task<Iterable<Showing>> task = () -> sDAO.listFiltered();

listFiltered()'s return type is Iterable<Showing>. How can I use the Task interface with lambda?

like image 851
Domien Avatar asked May 06 '15 23:05

Domien


1 Answers

Task is an abstract class, not an interface, and so it cannot be directly created with a lambda expression.

You would typically just use an inner class to subclass Task:

Task<Iterable<Showing>> task = new Task<Iterable<Showing>>() {
    @Override
    public Iterable<Showing> call throws Exception {
        return sDAO.listFiltered();
    }
});

If you want the functionality of creating a Task with a lambda expression, you could create a reusable utility method to do that for you. Since the abstract method call that you need to implement in Task has the same signature as the interface method in Callable, you could do the following:

public class Tasks {

    public static <T> Task<T> create(Callable<T> callable) {
        return new Task<T>() {
            @Override
            public T call() throws Exception {
                return callable.call();
            }
        };
    }
}

Since Callable is a FunctionalInterface (i.e. an interface with a single abstract method), it can be created with a lambda expression, so you could do

Task<Iterable<Showing>> task = Tasks.create(() -> sDAO.listFiltered());

There is an explanation of why lambdas are not allowed to be used to create (effectively) subclasses of abstract classes with a single abstract method on the OpenJDK mailing list.

like image 81
James_D Avatar answered Nov 14 '22 22:11

James_D