为了试图深入理解Java流和spliterator,我有一些关于spliterator特性的微妙问题:
Q1:stream.empty()
与stream.of()
(不带参数的stream.of())
stream.empty()
:已沉降,大小stream.of()
:沉降的、不可变的、有大小的、有序的为什么stream.empty()
不具有stream.of()
相同的特性?请注意,当它与stream.concat()结合使用时(特别是没有ordered
)会产生影响。我想说stream.empty()
不仅应该具有不可变和有序性,而且还应该具有DISTINCT和nonnull。stream.of()
只有一个参数具有distict。
Q2:longstream.of()
不具有非空值
刚刚注意到NONNULL在longstream.of
中不可用。nonnull
不是所有longstream
s、intstream
s和doublestream
s的一个主要特性吗?
Q3:longstream.range(,)
与longstream.range(,).boxed()
longrange.range(,)
:sumpled,IMMUTABLE,NONNULL,SIZED,ORDERED,SORTED,indistincelongstream.range(,).boxed()
:已添加、已调整大小、已排序为什么.boxed()
失去了所有这些特性?它不应该失去任何东西。
我知道.maptoobj()
可能会丢失非空、不可变和DISTICT,但.boxed()
...没道理。
Q4:.peek()
丢失不可变和非空
LongStream.of(1)
:已沉降,不可变,非空,大小已定,...LongStream.of(1).peek()
:已沉降,大小已定,...
为什么.peek()
会失去这些特性?.peek
应该不会丢失任何东西。
Q5:.skip()
,.limit()
丢失已平息、不可变、非空、大小
请注意,这些操作丢失了sumved、IMMUTABLE、NONNULL、size。为什么?如果大小是可用的,那么计算最终大小也是很容易的。
Q6:.filter()
丢失不可变、非空
请注意,这个操作同样会丢失summed、IMMUTABLE、NONNULL、size。失去sumded和size是有意义的,但其他两个就没有意义了。为什么?
我会很感激如果有人能深刻理解分裂者能带来一些澄清。多谢了。
我不得不承认,当我第一次试图找出特征的实际含义时,我也遇到了困难,并且感觉到它们的含义在Java ;8的实现阶段没有明确确定,因此使用不一致。
请考虑spliterator.immutable
:
表示元素源不能进行结构修改的特征值;也就是说,不能添加、替换或移除元素,因此在遍历期间不能发生这样的更改。
在这个列表中看到“replaced”是很奇怪的,当谈到列表
或数组时,它通常不被认为是结构修改,因此,接受数组(未克隆)的流和spliterator工厂报告不可变
,如longstream.of(…)
或arrays.spliterator(Long[])
。
如果我们更慷慨地将其解释为“只要客户端无法观察到”,则concurrent
没有显著区别,因为无论在哪种情况下,一些元素都将报告给客户端,而没有任何方法来识别它们是否是在遍历期间添加的,或者一些元素是否由于删除而未报告,因为没有方法来倒带拆分器并进行比较。
该规范继续:
不报告immutable
或concurrent
的拆分器应具有关于在遍历期间检测到的结构干扰的文档化策略(例如抛出concurrentModificationException
)。
这是唯一相关的事情,报告immutable
或concurrent
的拆分器保证永远不会抛出concurrentModificationException
。当然,concurrent
在语义上排除了sized
,但这对客户端代码没有任何影响。
事实上,这些特性并不用于流API中的任何内容,因此,不一致地使用它们不会在某些地方引起注意。
这也是为什么每个中间操作都具有清除并发
、不可变
和非空
特性的效果的解释:流实现不使用这些特性,其表示流状态的内部类也不维护这些特性。
同样,nonnull
也不会在任何地方使用,因此对于某些流不使用它没有任何影响。我可以追踪LongStream.of(…)
发出的数组的内部使用。spliterator(Long[],int,int)
委托拆分器。spliterator(Long[]array,int fromIndex,int toIndex,int additionalcharacteres)
:
返回的拆分器总是报告特征sized
和sumved
。调用方可以提供附加特征以供拆分器报告。(例如,如果已知数组不会被进一步修改,请指定immutable
;如果认为数组数据具有偶遇顺序,请指定ordered
)。通常可以使用arrays.spliterator(long[],int,int)
方法,该方法返回报告sized
、sumpeded
、immutable
和ordered
的拆分器。
注意(再次)immutable
特性的使用不一致。它再次被视为必须保证没有任何修改,同时arrays.spliterator
以及arrays.stream
和longstream.of(…)
将报告immutable
特性,即使按照规范,也不能保证调用方不会修改它们的数组。除非我们考虑设置一个元素不是一个结构修改,但是这样,整个区别又变得毫无意义了,因为数组不能进行结构修改。
并且明确规定了无nonnull
特性。虽然很明显,基元值不能是null
,而且spliterator.abstract
类总是注入非null
特性,但spliterator.spliterator.spliterator.
返回的spliterator.spliterator.不是从spliterator.abstractLongspliterator
继承的。
坏处是,这不可能在不改变规范的情况下固定下来,好的是,反正没有任何后果。
因此,如果我们忽略concurrent
、immutable
或nonnull
的任何问题(这些问题没有任何后果),我们就有
大小
和跳过
和限制
。这是一个众所周知的问题,它是由流API实现skip
和limit
方式的结果。其他的实现也是可以想象的。这也适用于无限流与limit
的组合,它应该具有可预测的大小,但给定当前的实现,它没有。
将stream.concat(…)
与stream.empty()
组合。一个空流不对结果顺序施加约束,这听起来很合理。但是stream.concat(…)
在只有一个输入没有顺序时释放顺序的行为是值得怀疑的。请注意,在订购方面过于激进并不是什么新鲜事,请看这篇关于一种行为的问答,这种行为最初被认为是故意的,但后来在Java 8更新60中被修正了。也许,stream.concat
也应该在此时讨论…
.boxed()
的行为很容易解释。当它像.maptoOBJ(Long::ValueOf)
那样幼稚地实现时,它就会使所有的知识松散,因为maptoOBJ
不能假定结果仍然是排序的或不同的。但Java ;9已经解决了这一问题。其中,LongStream.Range(0,10).Boxed()
具有SublizedSizedOrderedSortedDistinct
特性,保持与实现相关的所有特性。
问题内容: 为了尝试深入了解Java流和分隔符,我对 分隔符的特性 提出了一些微妙的问题: Q1:vs(不带参数的Stream.of()) :已 订阅 :已 预订, 不可 更改,已 预订 ,已 订购 为什么没有相同的特征?请注意,与Stream.concat()结合使用时会产生影响(特别是没有)。我要说的不仅应该是 IMMUTABLE和ORDERED ,还应该是 DISTINCT和NONNULL
本文向大家介绍require.js深入了解 require.js特性介绍,包括了require.js深入了解 require.js特性介绍的使用技巧和注意事项,需要的朋友参考一下 现在,Require.js是我最喜欢的Javascript编程方式。它可以使代码化整为零,并易于管理。而Require.js Optimizer能帮助我们将一个较大的应用分散成多个较小的应用,并通过依赖串联起来,最后在编
logstash 已经拥有数以百计的插件,并提供了一站式的部署方式,极大的方便了新手入门。但在实际运用上,我们终究会碰上其他人还没碰到过,或者碰到过但没公布出来完整解决方案的问题。可能是某些环境适配,可能是某个环节的性能不佳,可能是某处硬编码设置不合理,等等等等。这时候,了解一些 logstash 的代码逻辑,了解 logstash 之所以做出当前选择的缘由。是有助于解决实际问题的。 此外,log
问题内容: 我试图了解如何使用Golang和forks。情况如下,我在写一个依赖于library的库,这不是我的。 由于缺少我需要的一些方法,因此将其分叉到。但是,我不能只是这样做,库引用了自己,所以它坏了。 在本文中,他们提供了可能的解决方案: 现在,这充其量是hacky。从库代码中无法得知依赖项来自其他存储库。任何使用我的图书馆的人都无法使其正常运行。 由于dep有望成为正式的依赖管理器。我发
在这本教程的一开始 (第 6 章, 构建脚本基础) 你已经学习了如何创建简单的任务. 然后你也学习了如何给这些任务加入额外的行为, 以及如何在任务之间建立依赖关系. 这些仅仅是用来构建简单的任务. Gradle 可以创建更为强大复杂的任务. 这些任务可以有它们自己的属性和方法. 这一点正是和 Ant targets 不一样的地方. 这些强大的任务既可以由你自己创建也可以使用 Gradle 内建好的
问题内容: 我在理解Java 8中的接口时遇到了麻烦,尤其是在与and 接口有关的地方。我的问题是我根本无法理解和接口的是,作为一个结果,接口仍然有些模糊了我。 和和到底是什么,我如何使用它们?如果我愿意写我自己或(和可能是我自己在这个过程中),我应该怎样做和不能做? 我阅读了一些分散在网络上的示例,但是由于此处的所有内容仍然是新内容并且随时可能更改,因此示例和教程仍然非常稀疏。 问题答案: 几乎