使用连续的stream.flatMap时无法在异常时停止

时间:2014-07-06 17:14:49

标签: java intellij-idea java-8 java-stream

在IntelliJ IDEA中调试我的代码时,如果在流上使用连续的flatMap方法,则在某些情况下我不能停止异常。它不是在异常处停止,而是在第271行的API ReferencePipeline#flatMap方法中停止,帧堆栈根本不显示异常。这是最简单的例子:

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class AssertTest {
    public static void main(String[] args) {
        Arrays.asList(
            Arrays.asList(0, 0, 0),
            Arrays.asList(1, 1, 1),
            Arrays.asList(2, 2, 2)
        )
            .stream()
            .flatMap(a -> test1(a).stream())
            .flatMap(a -> test2(a).stream())
            .collect(Collectors.toSet());
    }
    private static List<List<Integer>> test1(List<Integer> ints) {
        return Arrays.asList(ints);
    }
    private static List<List<Integer>> test2(List<Integer> ints) {
        throw new RuntimeException();
    }
}

这是我在调试器中运行代码时在IDE中看到的内容:

enter image description here

如果我注释掉.flatMap(a -> test1(a).stream())的行,那么它会按预期停在异常处。断言也是如此(将throw new RuntimeException()替换为assert false并使用-ea运行。)

此问题仅涉及调试器:程序在异常崩溃后,堆栈跟踪包含发生异常的正确位置。

Exception in thread "main" java.lang.RuntimeException
    at mypkg.AssertTest.test2(AssertTest.java:23)
    at mypkg.AssertTest.lambda$main$1(AssertTest.java:16)
    at mypkg.AssertTest$$Lambda$2/14008398.apply(Unknown Source)
    at java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:267)
    at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
    at java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:580)
    at java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:270)
    at java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:512)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:502)
    at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
    at mypkg.AssertTest.main(AssertTest.java:17)

这是一个错误吗?如果是这样,它在任何地方都被提到如果没有,我应该在哪里报告:Jetbrains,Oracle?或者这是正确的行为吗?

1 个答案:

答案 0 :(得分:0)

以下是我在报告错误后从Jetbrains开发人员那里得到的答案:

http://youtrack.jetbrains.com/issue/IDEA-126981?replyTo=27-763411

  

只有当我将任何异常断点设置为仅在未捕获的异常上停止时,我才能重现它,是这种情况吗?

     

您的异常被捕获并在java中重新抛出,这是一个缺点   溪流:(你需要停止捕获的例外情况   能够停在你的代码中。

在捕获的异常中启用停止可以解决此问题。