[英]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.