Stream.of(a, b, c).parallel().map(Object::toString).iterator();
返回的迭代器是否保证按该顺序提供值 a
、b
、c
?
我知道toArray()
和collect()
保证集合的值顺序正确。此外,我并不是在问如何从迭代器生成流。
到目前为止,我发现最接近保证的是java.util.stream包文档中的以下语句:
除了被标识为显式不确定的操作(如findAny())之外,流是顺序执行还是并行执行都不会改变计算的结果。
可以说,iterator()
生成一个以不同顺序迭代的Iterator
将是“结果的变化”,就像生成一个包含不同顺序元素的List
将用于Collection()
一样。
< code>Stream.of方法用于从不关联的值创建流,返回一个有序的流。
返回元素为指定值的有序流。
根据 Java.util.stream 的软件包“边
效应”部分:
IntStream.range(0,5).parallel()。地图(x-
这意味着< code>parallel()
和< code>map()保留流是否是顺序的/有序的。
我已经跟踪了Stream的实现。
的创建到名为ReferencePipeline的类。
@Override
public final Iterator<P_OUT> iterator() {
return Spliterators.iterator(spliterator());
}
该实现的
iterator()
方法遵从Spliterator。iterator()
,其代码仅依赖于Spliterator
's的tryAdvance
方法来适应0.05 iterator接口,并且不会更改任何流特征:
public static<T> Iterator<T> iterator(Spliterator<? extends T>
spliterator) {
Objects.requireNonNull(spliterator);
class Adapter implements Iterator<T>, Consumer<T> {
boolean valueReady = false;
T nextElement;
@Override
public void accept(T t) {
valueReady = true;
nextElement = t;
}
@Override
public boolean hasNext() {
if (!valueReady)
spliterator.tryAdvance(this);
return valueReady;
}
@Override
public T next() {
if (!valueReady && !hasNext())
throw new NoSuchElementException();
else {
valueReady = false;
return nextElement;
}
}
}
return new Adapter();
}
、< code>map或< code>iterator都不会改变特征。事实上,< code>iterator使用底层流< code>Spliterator来迭代流元素。总之,是的,顺序是有保证的,因为< code>Stream.of
创建了一个“顺序有序流”,并且上面使用的任何操作:< code>parallel
这是规范中的一个疏忽。如果一个流有一个定义好的相遇顺序,那么它的目的就是让它的迭代器按照相遇顺序产生元素。如果流没有定义遇到顺序,迭代器当然会以某种顺序产生元素,但是顺序不会被定义。
我已经提交了错误JDK-8194952来跟踪规范的更改。
看起来其他人已经爬取了足够多的实现,以表明它确实会按遇到顺序生成元素。此外,我们的流测试依赖于此属性。例如,toList
收集器的测试断言列表中的元素以与从流的Iterator获得的顺序相同的顺序存在。因此,依赖于此行为可能是安全的,即使它还没有正式指定。
我有一个记录课程: 我创建了一个包含很多记录的大列表。只有第二个和第五个值,即i/10000和i,稍后分别由getter使用。 请注意,前10000条记录的类别2为0,接下来的10000条记录的类别1等,而值1按顺序为0-114999。 我创建了一个既并行又排序的流。 我有一个ForkJoinPool,它维护8个线程,这是我电脑上的内核数。 我使用这里描述的技巧将流处理任务提交给我自己的,而不是常
是否有任何保证在顺序和有序流上的操作是按遇到顺序处理的? 我是说,如果我有这样的代码: 是否可以保证它将按照生成范围的遇到顺序执行myFunction()调用? 我找到了Stream类的JavaDocs草案,它明确地说明了以下内容: 对于顺序流管道,如果管道源具有已定义的遇到顺序,则所有操作都按照管道源的遇到顺序执行。 但是它没有提到顺序流,这个例子是针对并行流的(我的理解是,顺序流和并行流都是正
问题内容: Javadoc 表示(重点是我): 该操作的行为明确地是不确定的。 对于并行流管道,此操作不能保证遵守流的遇到顺序 ,因为这样做会牺牲并行性的好处。对于任何给定的元素,可以在库选择的任何时间和线程中执行操作。如果操作访问共享状态,则它负责提供所需的同步。 Java 9 Early Access Javadoc中提供了相同的文本。 第一句话(“明确地不确定”)表明(但未明确说明)此方法未
我想在Java对象中处理列表。我必须确保处理所有的元素,以便我收到他们。 因此,我是否应该对我使用的每个调用? 或者,只要不使用并行性,只使用流就足够了吗?
的Javadoc表示(强调是我的): 此操作的行为显式不确定。对于并行流管道,此操作不能保证尊重流的相遇顺序,因为这样做会牺牲并行性的好处。对于任何给定的元素,操作可以在库选择的任何时间和线程中执行。如果操作访问共享状态,则它负责提供所需的同步。 同样的文本也出现在Java9早期访问Javadoc中。 如果forEach不保留遭遇顺序,则会引入bug。在报告针对NetBeans的bug之前,我想知
问题内容: 我有大量数据,并且想要调用缓慢但干净的方法,而不是调用带有第一个结果的副作用的快速方法。我对中间结果不感兴趣,所以我不想收集它们。 明显的解决方案是创建并行流,进行慢速调用,再次使流顺序进行,然后进行快速调用。问题是,所有代码都在单个线程中执行,没有实际的并行性。 示例代码: 如果我删除,代码将按预期执行,但是很明显,非并行操作将在多个线程中调用。 您能推荐一些有关这种行为的参考,或者