假设我有一个抛出运行时异常的方法。我正在使用a Stream来对列表中的项目调用此方法。
Stream
class ABC { public void doStuff(MyObject myObj) { if (...) { throw new IllegalStateException("Fire! Fear! Foes! Awake!"); } // do stuff... } public void doStuffOnList(List<MyObject> myObjs) { try { myObjs.stream().forEach(ABC:doStuff); } catch(AggregateRuntimeException??? are) { ... } } }
现在,我希望处理列表中的所有项目,并将单个项目上的所有运行时异常收集到“聚合”运行时异常中,该异常将在最后抛出。
在我的真实代码中,我正在进行第三方API调用,这可能会引发运行时异常。我想确保所有项目都已处理,并在最后报告所有错误。
我可以想到几种破解方法,例如map()捕获并返回异常的函数( ..shudder .. )。但是,有没有一种本机的方法可以做到这一点?如果没有,还有另一种方法可以完全实现它吗?
map()
在这种简单doStuff方法的情况下,void您只关心异常,可以使事情保持简单:
doStuff
void
myObjs.stream() .flatMap(o -> { try { ABC.doStuff(o); return null; } catch (RuntimeException ex) { return Stream.of(ex); } }) // now a stream of thrown exceptions. // can collect them to list or reduce into one exception .reduce((ex1, ex2) -> { ex1.addSuppressed(ex2); return ex1; }).ifPresent(ex -> { throw ex; });
但是,如果您的要求更加复杂,并且您更喜欢使用标准库,CompletableFuture则可以代表“成功或失败”(尽管有一些缺陷):
CompletableFuture
public static void doStuffOnList(List<MyObject> myObjs) { myObjs.stream() .flatMap(o -> completedFuture(o) .thenAccept(ABC::doStuff) .handle((x, ex) -> ex != null ? Stream.of(ex) : null) .join() ).reduce((ex1, ex2) -> { ex1.addSuppressed(ex2); return ex1; }).ifPresent(ex -> { throw new RuntimeException(ex); }); }