Domien
Domien

Reputation: 405

Lambda for JavaFX Task

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?

Upvotes: 7

Views: 3265

Answers (1)

James_D
James_D

Reputation: 209358

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.

Upvotes: 13

Related Questions