这个问题是基于这个问题的答案,stream.of和intstream.range之间的区别是什么?
IntStream.range(0, 4)
.peek(e -> System.out.println(e))
.sorted()
.findFirst();
System.out.println(
IntStream.range(0, 4)
.spliterator()
.hasCharacteristics(Spliterator.SORTED)
);
IntStream.range(0, 4)
.parallel()
.peek(e -> System.out.println(e))
.sorted()
.findFirst();
这将按任何顺序生成如下内容:
2
0
1
3
因此,我希望sorted
属性已经被删除,原因是parallel()
。但是,下面的代码也返回true
。
System.out.println(
IntStream.range(0, 4)
.parallel()
.spliterator()
.hasCharacteristics(Spliterator.SORTED)
);
为什么parallel()
不更改sorted
属性,并且由于打印了所有四个数字,那么即使sorted属性仍然存在,Java又如何知道流没有排序呢?
具体如何做到这一点是一个非常具体的实现细节。您必须深入挖掘源代码才能真正了解原因。基本上,并行和顺序管道的处理方式不同。看看abstractPipeline.evaluate
,它检查isParallel()
,然后根据管道是否并行执行不同的操作。
return isParallel()
? terminalOp.evaluateParallel(this, sourceSpliterator(terminalOp.getOpFlags()))
: terminalOp.evaluateSequential(this, sourceSpliterator(terminalOp.getOpFlags()));
然后查看sortedops.ofint
,您将看到它重写了两个方法:
@Override
public Sink<Integer> opWrapSink(int flags, Sink sink) {
Objects.requireNonNull(sink);
if (StreamOpFlag.SORTED.isKnown(flags))
return sink;
else if (StreamOpFlag.SIZED.isKnown(flags))
return new SizedIntSortingSink(sink);
else
return new IntSortingSink(sink);
}
@Override
public <P_IN> Node<Integer> opEvaluateParallel(PipelineHelper<Integer> helper,
Spliterator<P_IN> spliterator,
IntFunction<Integer[]> generator) {
if (StreamOpFlag.SORTED.isKnown(helper.getStreamAndOpFlags())) {
return helper.evaluate(spliterator, false, generator);
}
else {
Node.OfInt n = (Node.OfInt) helper.evaluate(spliterator, true, generator);
int[] content = n.asPrimitiveArray();
Arrays.parallelSort(content);
return Nodes.node(content);
}
}
如果opwrapsink
是一个顺序管道,则最终将调用它;如果它是一个并行流,则将调用opevaluateParallel
(顾名思义)。请注意,如果管道已经排序,opwrapsink
不会对给定的接收器执行任何操作(只是不加更改地返回它),但opevaluateParallex
总是计算拆分器。
还要注意,并行性和排序性并不是相互排斥的。您可以拥有一个具有这些特性的任意组合的流。
“排序”是拆分器
的一个特征。从技术上讲,它不是流
的特征(就像“Parallel”一样)。当然,parallex
可以创建一个具有全新特性的全新分裂器(从原始分裂器获取元素)的流,但为什么要这样做呢?Id想象一下,在任何情况下,您都必须以不同的方式处理并行流和顺序流。
为了试图深入理解Java流和spliterator,我有一些关于spliterator特性的微妙问题: Q1:与(不带参数的stream.of()) :已沉降,大小 :沉降的、不可变的、有大小的、有序的 为什么不具有相同的特性?请注意,当它与stream.concat()结合使用时(特别是没有)会产生影响。我想说不仅应该具有不可变和有序性,而且还应该具有DISTINCT和nonnull。只有一个参
哪些流操作使用、和拆分器特性?它们在这些操作中如何发挥作用? 我不是问这些标志是什么,这在文档中很容易找到。我在问哪些操作使用它们以及如何使用它们。
本文向大家介绍HTML5的新特性相关面试题,主要包含被问及HTML5的新特性时的应答技巧和注意事项,需要的朋友参考一下 (1) 绘画canvas (2) 用于媒介回放的video和audio元素 (3) 本地离线存储localStorage长期存储数据,浏览器关闭后数据不丢失 (4) sessionStorage的数据在浏览器关闭后自动删除 (5) 语义化更好的内容元素,比如article,foo
1. ENUM枚举 1.1 枚举概述 枚举是指将变量的值一一列出来,变量的值只限于列举出来的值的范围内。举例:一周只有7天,一年只有12个月等。 回想单例设计模式:单例类是一个类只有一个实例 那么多例类就是一个类有多个实例,但不是无限个数的实例,而是有限个数的实例。这才能是枚举类。 格式是:只有枚举项的枚举类 public enum 枚举类名 { 枚举项1,枚举项2,枚举项3…;
我正在尝试更新当前登录用户的密码。但它显示了零点异常。 配置文件控制器: ProfileService: 给我这个错误: 2019-07-09 01:55:04.284错误---[nio-8080-exec-8]o.g.web.errors.GrailsExceptionResolver: NullPointerExcture发生时处理请求:[POST] /profile/doPasswordCh
这个页面描述了新添加到 AutoHotkey_L 分支的功能,现在简称为“AutoHotkey 1.1”。 流程控制 Break LoopLabel 退出一个循环或任意数目的嵌套循环. Continue LoopLabel 继续循环, 即使在任意数目的嵌套循环中. For x,y in z 从头到为尾循环对象的内容. Loop Until 循环直到条件为真. 可用于任意类型的循环. Try..