Java 哪些操作保持秩序
TL;博士我正在寻找一个可以查找某个中间操作还是终端操作的地方。我在哪里可以找到这样的文件 编辑这不是的重复,因为该问题没有提供全面的操作列表 背景 报告说: 流是否具有遭遇顺序取决于源和中间操作 这在本书中重复 为了确保在整个流操作中维护顺序,您必须研究流的源、所有中间操作和终端操作的文档,了解它们是否维护顺序(或者源是否首先有顺序) 这一切都很好,但我应该查看哪些文档?在一个例子中提到,Java 哪些操作保持秩序,java,java-8,java-stream,Java,Java 8,Java Stream,TL;博士我正在寻找一个可以查找某个中间操作还是终端操作的地方。我在哪里可以找到这样的文件 编辑这不是的重复,因为该问题没有提供全面的操作列表 背景 报告说: 流是否具有遭遇顺序取决于源和中间操作 这在本书中重复 为了确保在整个流操作中维护顺序,您必须研究流的源、所有中间操作和终端操作的文档,了解它们是否维护顺序(或者源是否首先有顺序) 这一切都很好,但我应该查看哪些文档?在一个例子中提到,map保证了排序,但它没有详尽的列表。文档记录了一些中间操作,但不是全部。 例如: 返回一个流,该流包含将
map
保证了排序,但它没有详尽的列表。文档记录了一些中间操作,但不是全部。
例如:
返回一个流,该流包含将给定函数应用于该流元素的结果
这是一个中间操作
或
返回一个流,该流包含与给定谓词匹配的该流元素
这是一个中间操作
这些都没有描述它们是否保持有序
索赔:
实际上,默认情况下,每个中间操作都保留一个顺序。唯一的例外是:
- unordered(),用于删除排序约束
- sorted(),用于更改顺序
额外积分听起来有点像两个重复的答案——因为你链接的两个答案实际上都解释了事情。我不知道
map
或filter
是否应该明确表示它们保留了顺序;它们不依赖于任何以前的状态或任何其他状态(这些是无状态操作),因此就我所知,它们保持着秩序。我的看法是相反的,如果他们不保持秩序——这应该在文档中明确提到;如果从操作名称看不明显。
例如,Stream.generate
对我来说并不明显,如果它生成了一个有序的流;因此,它的文件中说:
返回无限顺序无序流,其中每个元素由提供的供应商生成
另一方面,sorted
和unordered
很明显(IMO)会改变顺序,至少当你把它们放进去的时候——你明确地说你不在乎顺序<代码>无序顺便说一句,为了满足这一点,我们不会进行任何随机操作,您可以阅读更多内容
一般有两种订单:加工订单和遭遇订单
您可以将遭遇顺序视为从左到右的处理(假设您有一个列表
或数组
)。因此,如果您有一个不改变顺序的管道-元素将被馈送到采集器
(或任何其他终端操作),如从左到右所示。不是所有的码头都是这样的。一个明显的区别是forEach
和forEach
;或者一个收集器.toSet
-它根本不需要保留初始订单。或者让我们将findAny
作为终端操作-显然,您不关心您想要哪个元素,那么为什么要麻烦首先以准确的顺序输入findAny
另一方面,处理顺序没有定义的顺序-对于并行处理尤其明显。因此,即使您的管道是并行的(并且元素在处理时绝对不保证任何顺序),它们仍然会按顺序馈送到终端操作——如果终端操作需要这样的顺序 在对源代码进行了一些研究之后,我总结了以下表格: 摘自: 下表显示了允许修改字符的操作类型:
| | DISTICTS | SORTED | ORDERED | SIZED | SHORT_CIRCUIT |
| ---------------------- | -------- | ------ | ------- | ----- | --------------|
| source stream | Y | Y | Y | Y | N |
| intermediate operation | PCI | PCI | PCI | PC | PI |
| terminal operation | N | N | PC | N | PI |
- Y-允许有
- P-May蜜饯
- C-五月放晴李>
- 我可以注射李>
- N-无效;我与手术有关
取自 下表显示了每个中间操作/终端操作可以打开和关闭的特性和标志:(
短路
仅在StreamOpFlag
标志的上下文中相关)
注意:p
(保留)标志添加到每个单元格中,但带有C
和I
(清除和注入)标志的单元格除外。
| | DISTINCT | SORTED | ORDERED | SIZED | SHORT_CIRCUIT |
| ---------------- | ----------| --------| ---------| -------| ---------------|
| filter | | | | C | |
| forEach | | | C | | |
| forEachOrdered | | | | | |
| allMatch | | | C | | I |
| distinct | I | | | C | |
| flatMap | C | C | | C | |
| anyMatch | | | C | | I |
| collect | | | | | |
| unOrdered | | | C | | |
| count | C | C | C | C | |
| findAny | | | C | | I |
| findFirst | | | | | I |
| flatMapToXXX | C | C | | C | |
| limit | | | | C | I |
| map | C | C | | | |
| mapToXXX | C | C | | | |
| max | | | | | |
| min | | | | | |
| noneMatch | | | C | | I |
| peek | | | | | |
| reduce | | | | | |
| skip | | | C | I | |
| sorted | | I | I | | |
| toArray | | | | | |
-清除李>C
-注入李>I
forEach
和forEachOrdered
之间的根本区别在于,forEach
不尊重每个合同的订单,即使当前实现可能没有在内部清除该标志;这种设置/清除逻辑并不真正适用于终端操作。此外,没有理由认为元素的顺序应该与count
操作相关,顺便说一句,在Java9中这可能是短路。同时说sort
清除并注入SORTED
没有多大意义,特别是因为它是稳定的……这个表只反映了执行的当前状态。他们为什么在终端操作中插入/清除标志也是一个值得研究的有趣问题。谢谢你的注释和编辑。嗯,这里有一些背景宣传