以下说法正确吗?
该
sorted()
操作是“有状态的中间操作”,这意味着后续操作不再对后备集合进行操作,而是对内部状态进行操作。
(来源和来源
-它们似乎是彼此复制或来自同一来源。)
我已经Stream::sorted
从上面的源代码中测试了一个片段:
final List<Integer> list = IntStream.range(0, 10).boxed().collect(Collectors.toList());
list.stream()
.filter(i -> i > 5)
.sorted()
.forEach(list::remove);
System.out.println(list); // Prints [0, 1, 2, 3, 4, 5]
有用。我换成Stream::sorted
用Stream::distinct
,Stream::limit
并且Stream::skip
:
final List<Integer> list = IntStream.range(0, 10).boxed().collect(Collectors.toList());
list.stream()
.filter(i -> i > 5)
.distinct()
.forEach(list::remove); // Throws NullPointerException
令我惊讶的NullPointerException
是,它被抛出了。
所有测试的方法都遵循有状态的中间操作特性。但是,这种独特的行为Stream::sorted
没有得到记录,Stream操作和管道部分也没有说明 有状态中间操作 是否真正保证了新的源集合。
我的困惑来自哪里,以上行为的解释是什么?
API文档没有这样的保证“后续操作将不再对后备集合进行操作”,因此,您永远不应依赖于特定实现的这种行为。
您的示例碰巧偶然地完成了所需的操作;甚至不能保证List
创建的by
collect(Collectors.toList())
支持该remove
操作。
展示一个反例
Set<Integer> set = IntStream.range(0, 10).boxed()
.collect(Collectors.toCollection(TreeSet::new));
set.stream()
.filter(i -> i > 5)
.sorted()
.forEach(set::remove);
抛出一个ConcurrentModificationException
。原因是实现已优化了此方案,因为源已被排序。原则上,它可以对原始示例进行相同的优化,就像forEach
不按指定顺序显式执行操作一样,因此不需要排序。
还有其他可以想象的优化,例如sorted().findFirst()
可以转换为“查找最小值”操作,而无需将元素复制到新存储中进行排序。
因此,最重要的是,当依赖于未指定的行为时,今天发生的事情可能会在明天添加新的优化措施而中断。
我一直试图理解和展示Java流如何在引擎盖下实现一种类型的循环融合,从而可以将几个操作融合到一个pass中。 这里的第一个例子是: 具有以下输出(对每一个元素的单一传递融合相当清楚): 所以我的问题是,在调用distinct时,我认为因为它是一个“有状态”的中间操作,所以它不允许在(所有操作的)一次传递过程中单独处理单个元素,这是正确的吗。此外,因为sorted()状态操作需要处理整个输入流以产生
问题内容: 我知道React可以异步并批量执行状态更新以优化性能。因此,在调用之后,您将永远无法相信要更新的状态。但是你可以信任的反应 更新相同的顺序状态被称为对 相同的组件? 不同的组件? 考虑在以下示例中单击按钮: 1. 在以下情况下,是否有可能 a为假而b为真 : 2. 在以下情况下,是否有可能 a为假而b为真 : 请记住,这些是我用例的极端简化。我意识到我可以以不同的方式进行操作,例如,在
我知道React可能会异步和批量地执行状态更新,以进行性能优化。因此,在调用之后,您永远不能相信会更新状态。但是,您是否信任React按照调用时的顺序更新状态 相同的组件? 不同的组件? 任何有文档支持的答案都是非常感谢的。
sismember key member 存在返回1,0表示不存在或者key不存在
问题内容: 考虑以下代码段: 很明显为什么最后一行 总是会 打印:我们正在使用引用标识比较,并且一个对象 永远不会 是已经存在的对象。 问题是关于前三行:这些比较是否 保证 在原始的情况下以及自动拆箱?在某些情况下,原语将被自动装箱,并执行参考身份比较吗?(然后全部变为!) 问题答案: 是。 JLS第5.6.2节指定了二进制数值提升的规则。部分: 当运算符将二进制数值提升应用于一对操作数时,每个操
AFAIK对流求和的唯一方法是: 这里的问题是,每次调用都会创建一个新的,而不是更改可变类型。 对于