Spliterator 中 estimatedSize 和 getExactSizeIfKnown 的区别

Difference between estimatedSize and getExactSizeIfKnown in Spliterator

我试图了解 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());})); 

estimateSize方法:

Returns an estimate of the number of elements that would be encountered by a forEachRemaining(java.util.function.Consumer<? super T>) traversal, or returns Long.MAX_VALUE if infinite, unknown, or too expensive to compute.

If this Spliterator is SIZED and has not yet been partially traversed or split, or this Spliterator is SUBSIZED and has not yet been partially traversed, this estimate must be an accurate count of elements that would be encountered by a complete traversal. Otherwise, this estimate may be arbitrarily inaccurate, but must decrease as specified across invocations of trySplit().

API Note:

Even an inexact estimate is often useful and inexpensive to compute. For example, a sub-spliterator of an approximately balanced binary tree may return a value that estimates the number of elements to be half of that of its parent; if the root Spliterator does not maintain an accurate count, it could estimate size to be the power of two corresponding to its maximum depth.

getExactSizeIfKnown 方法是:

Convenience method that returns estimateSize() if this Spliterator is SIZED, else -1.

Implementation Requirements:

The default implementation returns the result of estimateSize() if the Spliterator reports a characteristic of SIZED, and -1 otherwise.

这两个方法都引用了 SIZED,即:

Characteristic value signifying that the value returned from estimateSize() prior to traversal or splitting represents a finite size that, in the absence of structural source modification, represents an exact count of the number of elements that would be encountered by a complete traversal.

API Note:

Most Spliterators for Collections, that cover all elements of a Collection report this characteristic. Sub-spliterators, such as those for HashSet, that cover a sub-set of elements and approximate their reported size do not.

基于所有这些,如果 Spliterator 没有 SIZED characteristic.[=53=,这两种方法只会 return 不同的值]


在您的示例中,Spliterator 的来源是 ArrayList。如果我们看一下 ArrayList.spliterator():

的文档

Creates a late-binding and fail-fast Spliterator over the elements in this list.

The Spliterator reports Spliterator.SIZED, Spliterator.SUBSIZED, and Spliterator.ORDERED. Overriding implementations should document the reporting of additional characteristic values.

由于 SUBSIZED 特性,从 ArrayList 创建的 Spliterator——包括那些从 trySplit 产生的结果——永远不会有 estimateSizegetExactSizeIfKnown return 不同的值。