dma*_*a_k 1 java lambda casting type-inference java-8
假设我有一个具有这种签名的函数:
public static <T> List<Future<T>> invokeAll(Stream<Callable<T>> tasks) {
... submit given tasks using executor ...
}
Run Code Online (Sandbox Code Playgroud)
我有一个数据流,应该"包装"成可调用的并传递给这个函数.如下的天真映射不起作用:
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>
}));
Run Code Online (Sandbox Code Playgroud)
一种解决方案是返回返回lambda的lambda:
invokeAll(ids.map((id) -> {
return () -> {
// Do a long computation with given ID...
return Boolean.TRUE;
};
}));
Run Code Online (Sandbox Code Playgroud)
另一个(在某种程度上等效)是使用辅助函数:
public static <T> Callable<T> createCallable(T id) {
return () -> {
return id;
};
}
invokeAll(ids.map(ThisClass::createCallable));
Run Code Online (Sandbox Code Playgroud)
但也许有更好/更短的方式做同样的事情?例如,不知怎的告诉编译器它需要创建一个Callable返回给定值的东西:
invokeAll(ids.map((Function<String, Callable<Boolean>>) (id) -> {
// Do a long computation with given ID
return Boolean.TRUE;
}));
Run Code Online (Sandbox Code Playgroud)
谢谢你的任何建议.
让我们暂时忽略lambdas,因为我认为它们是混乱的根源.让我们使用好的旧匿名类:
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;
}
};
}
}
)
);
Run Code Online (Sandbox Code Playgroud)
你有效地问的是"我怎么能自动做到这一点:"
invokeAll(
ids.map(
new Function<String, Callable<Boolean>>()
{
@Override
public Callable<Boolean> apply(String str)
{
return Boolean.TRUE;
}
}
)
);
Run Code Online (Sandbox Code Playgroud)
当然,你不能.A Boolean不是Callable<Boolean>.所以解决方案仅限于您已经确定的内容:
1)使用lambda创建Callable:
() -> Boolean.TRUE
() -> { return Boolean.TRUE; }
Run Code Online (Sandbox Code Playgroud)
2)创建一个为您执行此操作的方法.这样的方法可能比选项#1更冗长,所以它不会让你获得任何东西.
对不起,没有别的办法可以让它自动化了.
| 归档时间: |
|
| 查看次数: |
103 次 |
| 最近记录: |