Java 8流中的汇总运行时异常 [英] Aggregate runtime exceptions in Java 8 streams

查看:191
本文介绍了Java 8流中的汇总运行时异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个抛出运行时异常的方法。我使用 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 ???){
...
}
}
}

现在我想要处理列表中的所有项目,并将单个项目上的任何运行时异常收集到一个聚合运行时异常中,这些异常将被抛出结束。



在我的真实代码中,我正在进行第三方API调用,这可能会抛出运行时异常。我想确保所有项目都被处理,任何错误报告在最后。



我可以想到几种方法来破解这一点,比如code> map()函数捕获并返回异常( .. shudder .. )。但是有没有本土的方式来做到这一点?如果没有,是否有另一种方法来实现它?

解决方案

在这种简单的情况下, doStuff 方法是 void ,你只关心例外情况,可以简单的说:

  myObjs.stream()
.flatMap(o - > {
try {
ABC.doStuff(o);
return null;
} catch(RuntimeException ex){
return Stream.of(ex);
}
})
//现在抛出异常的流。
//可以收集他们列出或减少一个例外
.reduce((ex1,ex2) - > {
ex1.addSuppressed(ex2);
return ex1;
})。ifPresent(ex - > {
throw ex;
});

但是,如果您的要求更加复杂,而您更喜欢使用标准库, 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);
});
}


Let's say I have a method which throws a runtime exception. I'm using a Stream to call this method on items in a list.

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) {
            ...
        }             
    }
}

Now I want all items in the list to be processed, and any runtime exceptions on individual items to be collected into an "aggregate" runtime exception which will be thrown at the end.

In my real code, I am making 3rd party API calls which may throw runtime exceptions. I want to make sure that all items are processed and any errors reported at the end.

I can think of a few ways to hack this out, such as a map() function which catches and returns the exception (..shudder..). But is there a native way to do this? If not, is there another way to implement it cleanly?

解决方案

In this simple case where the doStuff method is void and you only care about the exceptions, you can keep things simple:

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;
    });

However, if your requirements are more complicated and you prefer to stick with the standard library, CompletableFuture can serve to represent "either success or failure" (albeit with some warts):

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);
            });
}

这篇关于Java 8流中的汇总运行时异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆