Сократить вложенную лямбду - PullRequest
0 голосов
/ 02 февраля 2020

Я хочу сопоставить список задач с List<Callable<Tasks>>:

List<Callable<Tasks>> callableTasks = tasks.stream().map(t ->
        {
            // how to return callable directly and omitting curly braces?
            Callable<Task> task = () -> run(t);
            return task;
        }).collect(Collectors.toList());

Как мне сократить указанное выше выражение, чтобы вернуть вызываемый объект напрямую?

Ответы [ 2 ]

5 голосов
/ 02 февраля 2020

Вы можете использовать методы stati c из класса Executors, например Executors.callable:

tasks.stream().map(t -> callable(() -> run(t))).collect(Collectors.toList());
3 голосов
/ 03 февраля 2020

Проблема в том, что лямбда-выражение () -> 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, если вы используете версию с одним аргументом.

...