将一些调试打印添加到管道将显示 NullPointerException 的源代码:
list.stream().peek(string -> System.out.println("peek1 " + string)).filter(string -> string.equalsIgnoreCase("5")).peek(string -> System.out.println("peek2 " + string)).forEach(string -> removeMember(string));
此输出:
peek1 0
peek1 1
peek1 2
peek1 3
peek1 4
peek1 5
peek2 5
peek1 7
peek1 8
peek1 9
peek1 null
Exception in thread "main" java.lang.NullPointerException
at HelloWorld.lambda$main$1(HelloWorld.java:22)
at HelloWorld$$Lambda$2/303563356.test(Unknown Source)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:174)
at java.util.stream.ReferencePipeline$11$1.accept(ReferencePipeline.java:373)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:512)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:502)
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
at HelloWorld.main(HelloWorld.java:22)
当“5”从清单中删除时,从“6”到“9”的所有要素都向左移动了一个位置(即它们的指数减少了1)。Stream 管道未检测到它,因此它跳过了“6”,当它处理最后一个位置(最初包含“9”)时,它遇到了 null,这会导致何时对其进行评估。NullPointerException
string.equalsIgnoreCase("5")
这类似于您在这个传统循环中得到的:for
int size = list.size();
for (int i = 0; i < size; i++) {
String string = list.get(i);
if (string.equalsIgnoreCase("5"))
removeMember(string);
}
只有在这里你会得到而不是,因为当.我猜 Stream 管道直接在 的内部数组上工作,因此它不会检测到 List 的大小已更改。IndexOutOfBoundsException
NullPointerException
list.get(i)
i==9
ArrayList
编辑:
根据 Holger 的评论,我更改了代码以消除 (通过将筛选器更改为 )。这确实产生了:NullPointerException
filter(string -> "5".equalsIgnoreCase(string))
ConcurrentModificationException
peek1 0
peek1 1
peek1 2
peek1 3
peek1 4
peek1 5
peek2 5
peek1 7
peek1 8
peek1 9
peek1 null
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1380)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:512)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:502)
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
at HelloWorld.main(HelloWorld.java:22)