mmu*_*hid 20 java java-8 java-stream
给出以下代码:
List<String> strList = new ArrayList<>(Arrays.asList("Java","Python","Php"));
Stream<String> jFilter = strList.stream().filter(str -> str.startsWith("J"));
strList.add("JavaScript"); // element added after filter creation
strList.add("JQuery"); // element added after filter creation
System.out.println(Arrays.toString(jFilter.toArray()));
Run Code Online (Sandbox Code Playgroud)
哪个输出:
[Java, JavaScript, JQuery]
Run Code Online (Sandbox Code Playgroud)
即使在创建过滤后的流后添加了过滤结果,为什么会出现JavaScript并JQuery显示在过滤结果中?
Ous*_* D. 13
你在这一点之后假设:
Stream<String> jFilter = strStream.filter(str -> str.startsWith("J"));
Run Code Online (Sandbox Code Playgroud)
返回以"J"开头的元素的新流,即仅返回Java.然而事实并非如此;
流是懒惰的,即除非终端操作另有说明,否则它们不执行任何逻辑.
流管道的实际执行在toArray()调用时开始, 并且由于在终端toArray()操作开始之前修改了列表,结果将是[Java, JavaScript, JQuery].
这里提到的文档的一部分:
对于性能良好的流源,可以在终端操作开始之前修改源,并且这些修改将反映在所覆盖的元素中.例如,请考虑以下代码:
Run Code Online (Sandbox Code Playgroud)List<String> l = new ArrayList(Arrays.asList("one", "two")); Stream<String> sl = l.stream(); l.add("three"); String s = sl.collect(joining(" "));首先创建一个包含两个字符串的列表:"one"; 和"两个".然后从该列表创建流.接下来,通过添加第三个字符串来修改列表:"three".最后,收集流的元素并将它们连接在一起.由于在终端收集操作开始之前修改了列表,结果将是一串"一二三".从JDK集合和大多数其他JDK类返回的所有流都以这种方式表现良好;
直到声明
System.out.println(Arrays.toString(jFilter.toArray()));
Run Code Online (Sandbox Code Playgroud)
运行,流不做任何事情.toArray要遍历的流和执行中间操作(filter在这种情况下)需要终端操作(在示例中).
在这种情况下,您可以做的是,例如,在添加其他元素之前捕获列表的大小:
int maxSize = strList.size();
Stream<String> jFilter = strStream.limit(maxSize)
.filter(str -> str.startsWith("J"));
Run Code Online (Sandbox Code Playgroud)
哪里limit(maxSize)不允许超过初始元素通过管道.
| 归档时间: |
|
| 查看次数: |
530 次 |
| 最近记录: |