排序
Streams可能有也可能没有已定义的遭遇顺序。是否 一个流有一个遭遇顺序取决于源和 中间操作。某些流源(例如List或 数组)本质上是有序的,而其他的(如HashSet) 不是。某些中间操作(例如sorted())可能会强制执行 在其他无序流上遇到订单,其他人可能会 渲染无序的有序流,例如BaseStream.unordered()。 此外,一些终端操作可以忽略遭遇顺序,例如 的forEach()。
HashSet
?unordered
中间操作,它被认为是最佳做法将并行计算?答案 0 :(得分:5)
除了HashSet
和HashMap
的集合视图外,Stream.generate()
还会生成无序流。
毋庸置疑,Random
生成的流也是无序的。此外,Stream.empty()
没有报告有遭遇订单,但这没有太多后果......
如果您知道不需要Stream来维护遭遇顺序,那么使用unordered()
是一种很好的做法 - 即使它没有提高性能,就像当前实现中的大多数操作一样,它不会造成伤害,文件你不关心订单。这不仅适用于并行流,某些操作(如distinct()
)也可能受益于无序性,即使在顺序情况下也是如此。
在某些情况下,选择正确的终端操作,例如findAny()
而不是findFirst()
文档,这些文档意图更加简洁,并且在给定当前实现的情况下也会对性能产生更大的影响。
答案 1 :(得分:4)
遭遇秩序只不过是来源的顺序。例如。在ArrayList
中,元素按插入顺序排序,因此通过它进行流式处理将只按顺序为您提供元素。
HashSet
外,HashMap
也是无序的。如果您只对collect
操作感兴趣并且不关心订购,那么您无需担心。只需stream()
即可。
例如。如果你想说计算总和那么你会做这样的事情:
List<Integer> list = Arrays.asList(1,2,3);
int sum = list.stream().collect(Collectors.summingInt(e -> e));
在这种情况下,元素流入流中的顺序无关紧要。
答案 2 :(得分:2)
第二个问题是。如果您不关心这些,unordered
将提供帮助。我刚才有同样的问题,here。
现在想想没有订购。如果您有一个List并将每个元素乘以2并将其收集回List,则可以并行执行。中间列表的每次合并都必须以这样的方式发生,即订单保留在结果列表中。您可能已经计算了第4个和第一个中间结果,现在需要合并它们。如果你关心关于订单,你不能直接合并它们,因为这显然会破坏订单;所以你需要计算其他中间结果,并以相同的顺序合并它们。
您可能会想到这就像从左到右穿越List
;从索引零到最后一个。
另一方面,如果你不关心订单,那么只要它准备好就可以在任何订单中进行合并。你甚至可以按任何顺序读取任何元素,因为这是无关紧要的。
findFirst
和findAny
在后台使用相同的想法。假设您有一个包含8个元素的List,并行处理它并且只需要返回第一个元素。您可能已经处理了7个最后元素已经,但由于您需要第一个元素,因此无关紧要 - 您仍需要等待第一个元素处理。很明显为什么findAny
更好......