Java 深刻理解分配器的特性
为了深入理解java流和拆分器,我有一些关于拆分器特性的微妙问题: Q1:Java 深刻理解分配器的特性,java,java-8,java-stream,spliterator,Java,Java 8,Java Stream,Spliterator,为了深入理解java流和拆分器,我有一些关于拆分器特性的微妙问题: Q1:Stream.empty()vsStream.of()(Stream.of()不带参数) Stream.empty():子项,大小 Stream.of() 为什么Stream.empty()?请注意,它与Stream.concat()结合使用时会产生影响(特别是没有排序的)。我想说,Stream.empty()不仅应该具有不可变的和有序的属性,还应该具有独特的和非空的属性。而且,只有一个参数具有DISTICT,它才有意
Stream.empty()
vsStream.of()
(Stream.of()不带参数)
:子项,大小Stream.empty()
Stream.of()
Stream.empty()?请注意,它与Stream.concat()结合使用时会产生影响(特别是没有排序的
)。我想说,Stream.empty()
不仅应该具有不可变的和有序的属性,还应该具有独特的和非空的属性。而且,只有一个参数具有DISTICT,它才有意义Stream.of()
Q2:LongStream.of()
不具有非空值
刚才注意到NONNULL在
的LongStream.of中不可用。
NONNULL
不是所有LongStream
s、IntStream
s和DoubleStream
s的主要特征吗
Q3:LongStream.range(,)
vsLongStream.range(,).boxed()
长范围。范围(,)
:子化,不可变,非空,大小,顺序,排序,不同
LongStream.range(,).boxed()
:子项、大小、顺序
为什么.boxed()
会丢失所有这些特性?它不应该丢失任何东西
我知道.mapToObj()
可能会丢失非null、不可变和DISTICT,但是.boxed()
。。。没有道理
Q4:.peek()
将丢失不可变和非空值
LongStream.of(1)
:子化、不可变、非空、大小。。。
LongStream.of(1).peek()
:子化、大小化
为什么.peek()
会丢失这些特性.peek
不应该真的丢失任何东西
Q5:.skip()
,.limit()
丢失子项、不可变、非空、大小
请注意,这些操作将丢失子化的、不可变的、非空的、大小为的。为什么?如果尺寸可用,那么也很容易计算最终尺寸
Q6:.filter()
丢失不可变的非空值
请注意,此操作也会丢失子化、不可变、非空、大小。失去补贴和规模是有道理的,但其他两个没有道理。为什么?
如果有人对拆分器有深入的了解,能够提供一些清晰的信息,我将不胜感激。谢谢。我必须承认,当我第一次试图找出这些特性的实际含义时,我也遇到了困难,我觉得它们的含义在Java 8的实现阶段没有得到明确的解决,因此使用时不一致
考虑:
表示元素源在结构上无法修改的特征值;也就是说,不能添加、替换或删除元素,因此在遍历过程中不会发生此类更改
在这个列表中看到“替换”是很奇怪的,当谈到列表
或数组时,它通常不被视为结构修改,因此,流和拆分器工厂接受数组(未克隆)报告不可变
,如LongStream.of(…)
或Arrays.spliterator(长[])
如果我们更宽泛地解释为“只要客户不可见”,与并发
没有显著差异,因为在这两种情况下,有些元素将报告给客户端,而无法识别它们是在遍历过程中添加的还是由于删除而未报告的,因为无法回放拆分器并进行比较
本规范继续说明:
对于不报告不可变
或并发
的拆分器,在遍历过程中检测到的结构干扰方面,需要有一个文档化的策略(例如抛出并发修改异常
)
这是唯一相关的事情,IMMUTABLE
或CONCURRENT
报告的拆分器保证不会抛出ConcurrentModificationException
。当然,CONCURRENT
在语义上排除了大小的,但这对客户端代码没有影响
事实上,这些特性并没有用于流API中的任何内容,因此,不一致地使用它们永远不会引起注意
这也是为什么每个中间操作都具有清除并发
、不可变
和非空
特征的效果的原因:流实现不使用这些特征,并且表示流状态的内部类不维护它们
类似地,NONNULL
在任何地方都没有使用,因此它对于某些流没有任何影响。我可以跟踪(…)的LongStream.of
问题,直到数组的内部使用。拆分器(long[],int,int)
委托给
:
返回的拆分器始终报告特性大小
和子项
。调用者可能会提供其他特性供拆分器报告。(例如,如果已知数组不会被进一步修改,则指定不可变
;如果数组数据被认为具有遭遇顺序,则指定有序
)。方法数组.spliterator(long[],int,int)通常可以使用
,它返回一个拆分器,报告大小
、子项
、不可变
和有序
附注(aga)