如何转换代码以使用CompletableFuture? [英] How to convert the code to use CompletableFuture?
问题描述
我以前有一个可调用的类
I used to have a callable class
class SampleTask implements Callable<Double> {
@Override
public Double call() throws Exception {
return 0d;
}
}
我曾经使用 ExecutorService
提交 Callable
。如何更改为使用 CompletableFuture.supplyAsync
?
I used to use ExecutorService
to submit the Callable
. How to change to use CompletableFuture.supplyAsync
?
以下代码无法编译
SampleTask task = new SampleTask();
CompletableFuture.supplyAsync(task);
不存在变量类型U的实例,以便SampleTask符合供应商
No instance of type of variable U exists so that SampleTask conforms to Supplier
推荐答案
supplyAsync()
期望a 供应商< U>
并且您给它可调用
。
supplyAsync()
expects a Supplier<U>
and you are giving it a Callable
.
错误消息告诉您编译器已尝试查找用于 U
的类型,以便您的 SampleTask
是供应商< U>
,但找不到。
The error message is telling you that the compiler has tried to find a type to use for U
such that your SampleTask
"is a" Supplier<U>
, but it can't find one.
Java将将lambda隐式提升到功能界面,例如 Callable
或 Supplier
。但它不会将功能接口视为可互换 - 也就是说,您不能使用 Callable
其中供应商
是预期的。
Java will implicitly "promote" a lambda to a functional interface such as Callable
or Supplier
. But it won't treat functional interfaces as interchangeable -- that is, you can't use a Callable
where a Supplier
is expected.
你可以就地制作一个合适的lambda:
You can make a suitable lambda in-place:
SimpleTask task = new SimpleTask();
CompletableFuture.supplyAsync(() -> task.call());
请注意,如果 SimpleTask
,则此方法有效 call()
is:
Note that this works if SimpleTask
's call()
is:
public Double call() { // note no exception declared
return 0d;
}
SimpleTask
碰巧执行 Callable
与上面的代码无关。
The fact that SimpleTask
happens to implement Callable
is not relevant to the code above.
如果您希望使用任意可调用
,或者将任务
声明为 Callable
:
If you want this to work with an arbitrary Callable
, or if you declare task
as a Callable
:
Callable callable = new SimpleTask();
CompletableFuture.supplyAsync(() -> callable.call());
...然后您将收到有关未捕获异常的编译器错误。你的lambda将需要捕获异常并处理它(可能需要重新抛出作为未经检查的异常,如其他答案中所述)。
... then you will get a compiler error about the uncaught exception. Your lambda will need to catch the exception and handle it (perhaps rethrowing as an unchecked exception, as described in other answers).
或者您可以 SampleTask
实施供应商< Double>
。
lambdas的部分动机是编写像 Callable
这样的东西太冗长了。所以你可能会遗漏中间类并直接进入:
Part of the motivation for lambdas is that writing things like Callable
was too verbose. So you might well leave out the intermediate class and go directly for:
CompleteableFuture<Double> future = CompletableFuture.supplyAsync(() -> 0d);
这也适用于更复杂的供应商:
This applies for more complicated suppliers too:
CompleteableFuture<Double> future = CompletableFuture.supplyAsync(() -> {
Foo foo = slowQuery();
return transformToDouble(foo);
});
这篇关于如何转换代码以使用CompletableFuture?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!