如何减少 Java 中的 Futures 流?

mrb*_*ela 7 java reduce java-stream

假设我已经给出了一个Streamof Futures,我想通过调用该Stream#reduce方法来减少它。但我不想减少Futures本身,而是减少Future( Future#get)的结果。问题是,在这种情况下,get 方法可能会抛出一个ExecutionException并且不提供结果。

这就是为什么

Stream<Future<Integer>> stream = ...;
BinaryOperator<Integer> sum = (i1, i2) -> i1 + i2;  
stream.map(future -> future.get())
      .reduce(sum); // does not work, get needs to handle exceptions!
Run Code Online (Sandbox Code Playgroud)

所以,我必须捕捉异常:

stream.map(future -> {
    Integer i = null;
    try {
        i = future.get();
    } catch (InterruptedException e) {
    } catch (ExecutionException e) {}
    return i;
}).reduce(sum); 
Run Code Online (Sandbox Code Playgroud)

但是在这种方法中,我可能会遇到麻烦,因为null可能会出现值。

所以,为了摆脱这些,我必须过滤掉那些ExecutionException出现的:

stream.filter(future -> {
    Integer i = null;
    try {
        i = future.get();
    } catch (InterruptedException e) {
    } catch (ExecutionException e) {
    }
    return i != null;
})
.map(future -> {
    Integer i = null;
    try {
        i = future.get();
    } catch (InterruptedException e) {
    } catch (ExecutionException e) {
    }
    return i;
}).reduce(sum);
Run Code Online (Sandbox Code Playgroud)

我认为,这段代码会起作用.. 但我不想相信,这是减少 Futures 的唯一也是最聪明的方法。

有什么想法或建议吗?

Ben*_*oit 4

您可以先从 future 中提取值,然后过滤掉 null:

Integer result = stream
    .map(future -> {
        try {
          return future.get();
        } catch (InterruptedException | ExecutionException e) {
        }
        return null; })
    .filter(Objects::nonNull)
    .reduce(sum)
    .orElse(0);
Run Code Online (Sandbox Code Playgroud)