如何处理 Java 8 Stream 中的异常?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/43383475/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to handle Exception in Java 8 Stream?
提问by user3407267
I have a method where I am traversing through a List and creating List. While doing so, I am calling a method(createResult) to will give a Result also throws CustomException which I am wrapping as ResultClassException. But I keep getting an error saying Unhandled Exception.
我有一种方法可以遍历列表并创建列表。这样做时,我正在调用一个方法(createResult)来给出一个结果也会抛出 CustomException,我将其包装为 ResultClassException。但是我不断收到错误消息,说未处理的异常。
My Code :
我的代码:
private List<Result> getResultList(List<String> results) throws ResultClassException {
List<Result> resultList = new ArrayList<>();
results.forEach(
(resultName) -> {
if (!resultRepository.contains(resultName)) {
try {
final Result result = createResult(resultName);
resultList.add(result);
} catch (CustomException e) {
throw new ResultClassException("Error",e);
}
} else {
resultList.add(resultRepository.get(resultName));
log.info("Result {} already exists.", resultName);
}
}
);
return Collections.unmodifiableList(resultList);
}
Can Someone tell what I am doing wrong?
有人能告诉我我做错了什么吗?
回答by Olivier Grégtheitroade
You probably have too many responsibilities in your method. You should think about splitting it into a method that only maps and another one that gathers them.
你的方法可能有太多的责任。您应该考虑将其拆分为一个只映射的方法和另一个收集它们的方法。
private List<Result> getResultList(List<String> names) throws ResultClassException {
try {
return names.stream()
.map(this::getOrCreateResult)
.collect(collectingAndThen(toList(), Collections::unmodifiableList));
} catch (RuntimeException e) {
if (e.getCause() instanceof CustomException) {
throw new ResultClassException("Error", e.getCause());
}
throw e;
// Or use Guava's propagate
}
}
private Result getOrCreateResult(String name) {
if (!resultRepository.contains(name)) {
try {
return createResult(name);
} catch (CustomException e) {
throw new RuntimeException(e);
}
} else {
log.info("Result {} already exists.", name);
return resultRepository.get(name);
}
}
回答by msuper
I wouldn't suggest using RuntimeException as that would drive you into poor coding practice. Try to handle ResultClassException in the calling method of getResultList(...).
我不建议使用 RuntimeException,因为这会导致您陷入糟糕的编码实践。尝试在 getResultList(...) 的调用方法中处理 ResultClassException。
回答by strash
With the lambda expressions in Java 8 you are representing inner classes. So the exception will be thrown inside your anonymous inner class. try to add that where you are adding your the throw new ResultClassException("Error",e);
使用 Java 8 中的 lambda 表达式,您可以表示内部类。所以异常将在您的匿名内部类中抛出。尝试添加您要添加的地方 throw new ResultClassException("Error",e);
Thread.getAllStackTraces()
.keySet()
.stream()
.map(Thread::getStackTrace)
.map(Arrays::asList)
.forEach(list -> System.out.println(list.stream()
.map(i -> i.toString())
.collect(Collectors.joining("\n\t"))));
and see the thread that is calling it. You will see that your exception is out of the scope you expected with the lambdas. You will see that the stream is creating many threads and your exception is not part of the thread you want. You can wrap your method like that:Java 8: How do I work with exception throwing methods in streams?
并查看调用它的线程。您将看到您的异常超出了您对 lambda 的预期范围。您将看到该流正在创建许多线程,并且您的异常不是您想要的线程的一部分。 您可以像这样包装您的方法:Java 8:如何在流中使用异常抛出方法?
回答by santosh-patil
You can't handle a checked exception from inside of Streams
One workaround can be to throw a RuntimeException
from createResult
or write a method to wrap createResult
which will catch and handle the checked exception.
一种解决方法是抛出一个RuntimeException
fromcreateResult
或编写一个方法来包装createResult
,该方法将捕获并处理已检查的异常。