Search code examples
javajava.util.concurrent

use Executors.callable() within lambda


I have the following which works:

var tasks = tasks.stream(a -> (Callable<Set<FinishedTask>>) () -> call(a)).collect(Collectors.toList());

I want to change the above code to use Executors.callable

// how to cast executor.callable?
var tasks = tasks.stream(t -> (Set<FinishedTask>)Executors.callable(()-> call(t))).collect(Collectors.toList());

However, I get the compiler error:

The method callable(Runnable) is ambiguous for the type Executors

What is wrong with the cast?


Solution

  • You have two issues here.

    First this type of error, java cannot infer which method to call.

    Callable<?> c = Executors.callable( (PrivilegedAction) () -> "tested" );
    

    By using a cast you can tell java to use Executors.callable(PrivilegedAction) instead of Executors.callable(PrivilegedExceptionAction). They both have the same method signature. Runnable is not mistaken in this case because it is a void return type.

    Second, now it will know which method to use, but it is still returning a Callable, so you cannot just cast it to a set.

    Callable<Set<FinishedTask>> callable = () -> call(a);
    Callable<Set<FinishedTask>> callable2 = Executors.callable(()-> call(t));
    

    You're trying to cast to a set. You need to call.

    Set<FinishedTask> sft = Executors.callable(()-> call(t)).call();