繁体   English   中英

如何减少 Java 中的 Futures 流?

[英]How to reduce a stream of Futures in Java?

假设我已经给出了一个Stream of 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!

所以,我必须捕捉异常:

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

但是在这种方法中,我可能会遇到麻烦,因为可能会出现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);

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

有什么想法或建议吗?

您可以先从未来中提取值,然后过滤掉空值:

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

简化它的方法之一可能是:

void reduceImpl(Stream<Future<Integer>> stream) {
    Optional<Integer> integerOptional = stream
            .map(this::transform)
            .filter(Objects::nonNull)
            .reduce(Integer::sum);
}

private Integer transform(Future<Integer> future) {
    try {
        return future.get();
    } catch (InterruptedException | ExecutionException e) {
        return null; // should ideally be handled properly
    }
}

您可以使用flatMap做到这一点:

    public static void main(String[] args) {
        Stream<Future<Integer>> yourStream = null;

        int sum = yourStream.flatMap(YourClass::unpack)
            .mapToInt(Integer::intValue)
            .sum()
            .orElse(0);
    }

    public static <T> Stream<T> unpack(Future<T> future) {
        try {
            return Stream.of(future.get());
        } catch (InterruptedException e) {
            return Stream.empty();
        } catch (ExecutionException e) {
            return Stream.empty();
        }
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM