创建Stream后更改Stream的源时Stream的行为

gar*_*kaj 0 java java-8 java-stream

考虑下面的这段代码:

     List<Integer> l=new ArrayList<>();
     l.add(23);l.add(45);l.add(90);

     Stream<Integer> str=l.stream();     // mark A

     l.add(111);
     l=null;

     System.out.println(str.collect(Collectors.toList())); // mark B
Run Code Online (Sandbox Code Playgroud)

输出是:

[23, 45, 90, 111]
Run Code Online (Sandbox Code Playgroud)

我在这里假设,当在标记B处调用终端操作时,将评估标记A的RHS,这意味着已选择了最近的列表(带有元素“ 111”),但问题是为什么我们没有 NullPointerException来到这里。没有得到异常,那么我们也不应该在输出中得到“ 111”。.请帮助。

Hol*_*ger 5

此行为在文档中明确说明:

对于行为良好的流源,可以在终端操作开始之前修改源,并且这些修改将反映在所涵盖的元素中。例如,考虑以下代码:

List<String> l = new ArrayList(Arrays.asList("one", "two"));
Stream<String> sl = l.stream();
l.add("three");
String s = sl.collect(joining(" "));
Run Code Online (Sandbox Code Playgroud)

首先,创建一个由两个字符串组成的列表:“一个”;和“两个”。然后从该列表创建一个流。接下来,通过添加第三个字符串“三”来修改列表。最后,将流中的元素收集起来并结合在一起。由于列表是在终端collect 操作开始之前修改的,因此结果将是字符串“一二三”。从JDK集合返回的所有流以及大多数其他JDK类都以这种方式表现良好。有关其他库生成的流的信息,请参阅 低级流构建以了解构建行为良好的流的要求。