Проблема в том, что лямбда-выражение () -> run(t)
требует тип цели .
В конструкции типа
List<Callable<Tasks>> callableTasks = tasks.stream()
.map(…).collect(Collectors.toList());
Назначение List<Callable<Tasks>> callableTasks
обеспечивает целевой тип для вызова метода collect
, но не может распространить его на предыдущий вызов map
(общее ограничение текущего вывода типа Java).
Путем разбиения функции отображения на присваивание и return
, вы указываете целевой тип. Аналогично, вы могли бы предоставить целевой тип путем приведения, например, .map(t -> (Callable<Task>)() -> run(t))
или путем предоставления явного типа для обобщенного c метода map
, например, .<Callable<Task>>map(t -> () -> run(t))
.
Последнее решение приводит к
List<Callable<Task>> callableTasks = tasks.stream()
.<Callable<Task>>map(t -> () -> run(t)).collect(Collectors.toList());
Если экземпляр Task
, возвращаемый run(t)
, совпадает с передаваемым ему в качестве аргумента, вы можете использовать Executors.callable
, например:
List<Callable<Task>> callableTasks = tasks.stream()
.map(t -> Executors.callable(() -> run(t), t)).collect(Collectors.toList());
Обратите внимание на инкапсуляцию Executors.callable
Runnable
, который не возвращает значения. Таким образом, построенный Callable
будет оценивать результат, указанный как Executors.callable
в качестве второго аргумента или null
, если вы используете версию с одним аргументом.