使用Java 8 API流式处理CompletableFuture时出现编译错误
问题排查:简化CompletableFuture流式代码的编译错误
我来帮你找出这段简化代码的问题所在~
首先看你简化后的代码报错的核心原因:allDoneFuture.thenApply(...)返回的是CompletableFuture<OptionalLong>类型,而不是OptionalLong,你直接在这个CompletableFuture实例上调用getAsLong()方法,而CompletableFuture类并没有这个方法,这就导致了编译错误。
修正后的可运行代码
public Long getMaxSalary(List<CompletableFuture<EmployeeData>> futures) throws InterruptedException, ExecutionException { CompletableFuture<Void> allDoneFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()])); return allDoneFuture.thenApply(v -> futures.stream() .map(f -> f.join()) .mapToLong(r -> r.salary()) .max()) .get() // 先获取CompletableFuture中的OptionalLong结果 .getAsLong(); }
详细解释
thenApply的返回值类型:thenApply方法会返回一个新的CompletableFuture,它的泛型类型是你lambda表达式返回的类型——也就是OptionalLong。所以你需要先调用get()(或者join(),如果不需要处理检查异常的话)来获取CompletableFuture内部的OptionalLong实例。- 异常处理:
get()方法会抛出InterruptedException和ExecutionException,所以要么在方法上声明抛出这两个异常,要么用try-catch块包裹处理。如果想用更简洁的方式避免检查异常,可以把get()换成join(),join()只会抛出未检查的CompletionException。
另外,还有一个小优化点:你可以用方法引用让代码更简洁,修改后的代码如下:
public Long getMaxSalary(List<CompletableFuture<EmployeeData>> futures) { CompletableFuture<Void> allDoneFuture = CompletableFuture.allOf(futures.toArray(new CompletableFuture[futures.size()])); return allDoneFuture.thenApply(v -> futures.stream() .map(CompletableFuture::join) .mapToLong(EmployeeData::salary) .max()) .join() .getAsLong(); }
内容的提问来源于stack exchange,提问作者brain storm
相关产品推荐
相关产品推荐

