【发布时间】:2018-11-29 20:04:32
【问题描述】:
假设我有一个带有这样签名的函数:
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;
}));
感谢您的任何建议。
【问题讨论】:
-
实际上,第一个 sn-p 所需的唯一区别是将
(id) -> {更改为(id) -> () -> {。为什么你认为这 4 个字符需要一个辅助方法? -
我不明白您为什么要隐藏
Callable部分。在 lambda 前面添加一个() ->只是一个,所以没什么大不了的。 -
感谢您的 cmets!这对我来说是一个发现,从句法上讲,表达式可以写得更短,例如
invokeAll(ids.map((id) -> () -> Boolean.TRUE));. -
更短:
invokeAll(ids.map(id -> () -> true));...
标签: java lambda casting java-8 type-inference