5

我试图了解 Spliterator 的功能并遇到了这两种方法estimatedSizegetExactSizeIfKnown我可以弄清楚是什么estimatedSize但不确定到底是做getExactSizeIfKnown什么的。有人可以举一个例子来解释两者之间的区别。

编辑:我尝试了以下示例,其中两者都相同。在哪些情况下它们会有所不同?

public static void main(String[] args) {
        List<Integer> l = new ArrayList<>();
        l.add(1);
        l.add(2);
        l.add(3);
        Spliterator<Integer> s= (Spliterator<Integer>) l.spliterator();
    Spliterator<Integer> s1=s.trySplit();
    while(s.tryAdvance(n -> {System.out.print(n+" ");System.out.println("estimateSize "+s.estimateSize()+" getexactsizeifknown "+s.getExactSizeIfKnown());})); 
4

1 回答 1

5

estimateSize方法:

forEachRemaining(java.util.function.Consumer<? super T>)返回遍历将遇到的元素数量的估计值,或者Long.MAX_VALUE在无限、未知或计算过于昂贵时返回。

如果这个 Spliterator 已经SIZED并且还没有被部分遍历或拆分,或者这个 Spliterator 已经SUBSIZED并且还没有被部分遍历,那么这个估计必须是完整遍历时会遇到的元素的准确计数。否则,这个估计可能是任意不准确的,但必须根据调用的指定减少trySplit()

API 注释:

即使是不精确的估计,通常也是有用且计算成本低廉的。例如,近似平衡二叉树的子分离器可能会返回一个值,该值估计元素数量是其父元素数量的一半;如果根 Spliterator 没有保持准确的计数,它可以将大小估计为与其最大深度相对应的 2 的幂。

getExactSizeIfKnown方法是:

estimateSize()如果此 Spliterator 为,则返回的便捷方法SIZED,否则-1

实施要求:

estimateSize()如果 Spliterator 报告 的特征,则默认实现返回结果,SIZED否则返回-1

这两种方法都引用SIZED了,这是一个:

特征值表示从estimateSize()遍历或拆分之前返回的值表示有限大小,在没有结构源修改的情况下,表示完整遍历将遇到的元素数量的精确计数。

API 注释:

大多数用于集合的拆分器,涵盖了Collection报告此特征的所有元素。子分隔符,例如 的子分隔符,HashSet覆盖了元素的子集并近似于它们报告的大小。

Spliterator基于所有这些,如果不具有SIZED 特性,这两种方法只会返回不同的值。


在您的示例中, 的来源SpliteratorArrayList. 如果我们看一下以下文档ArrayList.spliterator()

在此列表中的元素上创建后期绑定和快速失败。Spliterator

Spliterator报告Spliterator.SIZEDSpliterator.SUBSIZEDSpliterator.ORDERED。_ 覆盖实现应记录附加特征值的报告。

由于这个SUBSIZED特性,Spliterator从一个创建的ArrayList——包括那些从——产生的trySplit将永远不会有estimateSizegetExactSizeIfKnown返回不同的值。

于 2019-03-30T04:11:51.523 回答