2017-06-02 45 views
5

https://docs.oracle.com/javase/8/docs/api/java/util/Spliterator.htmlSpliterator - 尺寸VS subsized標誌

SIZED特性值表示該值從 estimateSize()之前返回到遍歷或分裂表示有限 尺寸,在不存在結構源修改, 表示完整遍歷遇到的元素數量的精確計數。

SUBSIZED特徵值,表示由trySplit()產生的所有Spliterator 將同時爲SIZED和SUBSIZED。

  1. 有一種情況,當上漿的標誌上,但SUBSIZED標誌爲無效?
  2. 有沒有SUBSIZED標誌打開但SIZED標誌關閉的情況?

回答

7

一個SpliteratorSIZED但不SUBSIZED的一個典型的例子,是從HashMap創建的Spliterator。它將維持其內部條目陣列的範圍,其中一些陣列條目爲null,因爲容量高於實際大小。要跳過的null條目的確切分佈取決於所包含密鑰的哈希代碼。

因此,Spliterator最初確實知道它的(總)尺寸,但是當分割範圍時,它不知道每個範圍中有多少個元素。 HashMap所具有的元素越多,大致平衡分割的可能性就越高,所以這種策略是合理的,但確切的子集不是已知的,並且需要對數組進行迭代才能找到。

報告SUBSIZED特徵沒有SIZED是沒有意義的,據我所知,它甚至不是有效的。

+0

在HashMap中,如果我不知道有多少值等於null,SIZED標記的大小如何? –

+3

'HashMap'始終保持其大小,它是一個簡單的'int'變量。所以它確實知道*有多少* null值;它是容量(數組長度)和「大小」之間的差異,但它不知道它們是如何分佈在數組中的。 – Holger

+2

@Holger如果它的'內部數組是分裂的,我猜碰撞也會使子尺寸未知,對吧?例如,第一個桶可以有3個條目,而其他桶有0個或1個。我理解正確嗎? –

2

有點晚了,但仍然..前段時間也讓我感到困惑。我將列舉我所知道的那些:

HashMap(如上所述),因此IdentityHashMapLinkedHashMapTreeMap

這裏要注意的是ConcurrentHashMap不在列表中,因爲它允許併發更新,所以它的大小實際上是調用時的大小。其實CHM顯然還沒有報告SIZED

然後有那些涉及到Map,如HashSetTreeSet,因爲內部這些仍然地圖。

然後還有一個就是有點未預期在這裏面對位集合爲此BitSetSpliterator#characteristics樣子:

@Override 
    public int characteristics() { 
     // Only sized when root and not split 
     return (root ? Spliterator.SIZED : 0) | 
      Spliterator.ORDERED | Spliterator.DISTINCT | Spliterator.SORTED; 
    } 

這可能看起來很有趣,但對此的解釋是:

// Raise the index of this spliterator to be the next set bit 
// from the mid point 
index = nextSetBit(mid, wordIndex(hi - 1)); 

因此對於BitSet這隻會發生一次,因此報告SUBSIZED是沒有意義的,因爲拆分不會發生在中間。

另一種方法根本沒有意義:報告SUBSIZED但不是SIZED,所以沒有人(就我看代碼中)那樣做。