如何转换代码以使用CompletableFuture? [英] How to convert the code to use CompletableFuture?

查看:376
本文介绍了如何转换代码以使用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆