6

https://docs.oracle.com/javase/8/docs/api/java/util/Spliterator.html

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

SUBSIZED 特征值,表示由 trySplit() 产生的所有拆分器都将是 SIZED 和 SUBSIZED。

  1. 是否存在 SIZED 标志打开但 SUBSIZED 标志关闭的情况?
  2. 是否存在 SUBSIZED 标志打开但 SIZED 标志关闭的情况?
4

2 回答 2

11

Spliteratora that is SIZEDbut not的一个典型例子SUBSIZEDSpliterator从 a 创建HashMap。它将维护其内部条目数组的范围,其中一些数组条目为null,因为容量高于实际大小。要跳过的条目的确切分布null取决于所包含键的哈希码。

所以Spliterator最初确实知道它的(总)大小,但是在分割范围时,它不知道每个范围中有多少元素。元素越多HashMap,大致平衡分割的可能性就越高,所以这个策略是合理的,但是确切的子大小是未知的,它需要对数组进行迭代才能找到。

报告一个SUBSIZED特征SIZED没有意义,据我所知,甚至是无效的。

于 2017-06-02T15:45:35.703 回答
2

有点晚了,但仍然......这也让我困惑了一段时间。我将列举我知道的那些:

HashMap(如上所述),因此IdentityHashMapLinkedHashMapTreeMap

这里要注意的ConcurrentHashMaplist 中不存在它,因为它允许并发更新,所以它的大小实际上是调用时的大小。事实上CHM,甚至没有SIZED明显的报告。

然后是那些与MapHashSet和相关的TreeSet,因为在内部这些仍然是地图。

面对BitSet,这里有点出乎意料,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,所以没有人(据我在代码中查看)这样做。

于 2017-06-02T21:23:33.737 回答