如何将lambda类型强制为特定类型?

时间:2018-06-20 15:57:00

标签: java lambda casting java-8 type-inference

假设我有一个带有这种签名的函数:

public static <T> List<Future<T>> invokeAll(Stream<Callable<T>> tasks) {
   ... submit given tasks using executor ...
}

,我有一个数据流,应该将其“包装”为可调用并传递给此函数。像下面这样的幼稚映射不起作用:

Stream<String> ids = Stream.of("1", "2", "3");

invokeAll(ids.map((id) -> {
    // Do a long computation with given ID...
    return Boolean.TRUE; // Compilation error: Type mismatch: cannot convert from Boolean to Callable<Object>
}));

一种解决方案是返回返回lambda的lambda:

invokeAll(ids.map((id) -> {
    return () -> {
        // Do a long computation with given ID...
        return Boolean.TRUE;
    };
}));

另一个(以某种方式等效)是使用辅助函数:

public static <T> Callable<T> createCallable(T id) {
    return () -> {
        return id;
    };
}

invokeAll(ids.map(ThisClass::createCallable));

但是也许有更好/更短的方法可以做到这一点?例如。以某种方式告诉编译器它需要创建一个返回给定值的Callable

invokeAll(ids.map((Function<String, Callable<Boolean>>) (id) -> {
    // Do a long computation with given ID
    return Boolean.TRUE;
}));

感谢您的任何建议。

1 个答案:

答案 0 :(得分:5)

让我们暂时忽略lambda,因为我认为它们是造成混乱的原因。让我们使用good old匿名类:

invokeAll(
    ids.map(
        new Function<String, Callable<Boolean>>()
        {
            @Override
            public Callable<Boolean> apply(String str)
            {
                return new Callable<Boolean>()
                {
                    @Override
                    public Boolean call() throws Exception
                    {
                        return Boolean.TRUE;
                    }
                };
            }
        }
    )
);

您实际上要问的是“我如何自动执行此操作:”

invokeAll(
    ids.map(
        new Function<String, Callable<Boolean>>()
        {
            @Override
            public Callable<Boolean> apply(String str)
            {
                return Boolean.TRUE;
            }
        }
    )
);

当然,您不能Boolean不是Callable<Boolean>。因此,解决方案仅限于您已经确定的解决方案:

1)使用lambda创建Callable

() -> Boolean.TRUE 
() -> { return Boolean.TRUE; }

2)创建一个为您执行此操作的方法。这样的方法可能比选项#1更冗长,因此不会为您带来任何好处。

对不起,没有其他办法可以自动地使它变得更好。