Spliterator - 大小旗帜与小型旗帜
Spliterator - sized vs subsized flags
https://docs.oracle.com/javase/8/docs/api/java/util/Spliterator.html
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.
SUBSIZED Characteristic value signifying that all Spliterators
resulting from trySplit() will be both SIZED and SUBSIZED.
- 是否存在SIZED标志为on而SUBSIZED标志为off的情况?
- 是否存在SUBSIZED标志为on但SIZED标志为off的情况?
Spliterator
是 SIZED
但不是 SUBSIZED
的典型示例是从 HashMap
创建的 Spliterator
。它将在其内部条目数组上保持一个范围,其中一些数组条目为 null
,因为容量高于实际大小。要跳过的 null
个条目的确切分布取决于包含的键的哈希码。
所以 Spliterator
一开始确实知道它的(总)大小,但是在拆分范围时,它不知道每个范围中有多少个元素。 HashMap
的元素越多,大致平衡拆分的可能性就越大,所以这个策略是合理的,但是具体的子大小是未知的,需要对数组进行迭代才能找出。
在没有 SIZED
的情况下报告 SUBSIZED
特征毫无意义,据我所知,甚至无效。
有点晚了,但还是..这也让我前段时间感到困惑。我会列举我知道的那些:
HashMap
(如上所述),因此 IdentityHashMap
、LinkedHashMap
和 TreeMap
。
这里要注意的是ConcurrentHashMap
不在列表中,因为它允许并发更新,所以它的大小实际上是通话的那一刻。事实上 CHM
甚至没有报告 SIZED
很明显。
然后是与 Map
相关的那些,例如 HashSet
和 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
,所以没有人(据我查看代码)那样做。
https://docs.oracle.com/javase/8/docs/api/java/util/Spliterator.html
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.
SUBSIZED Characteristic value signifying that all Spliterators resulting from trySplit() will be both SIZED and SUBSIZED.
- 是否存在SIZED标志为on而SUBSIZED标志为off的情况?
- 是否存在SUBSIZED标志为on但SIZED标志为off的情况?
Spliterator
是 SIZED
但不是 SUBSIZED
的典型示例是从 HashMap
创建的 Spliterator
。它将在其内部条目数组上保持一个范围,其中一些数组条目为 null
,因为容量高于实际大小。要跳过的 null
个条目的确切分布取决于包含的键的哈希码。
所以 Spliterator
一开始确实知道它的(总)大小,但是在拆分范围时,它不知道每个范围中有多少个元素。 HashMap
的元素越多,大致平衡拆分的可能性就越大,所以这个策略是合理的,但是具体的子大小是未知的,需要对数组进行迭代才能找出。
在没有 SIZED
的情况下报告 SUBSIZED
特征毫无意义,据我所知,甚至无效。
有点晚了,但还是..这也让我前段时间感到困惑。我会列举我知道的那些:
HashMap
(如上所述),因此 IdentityHashMap
、LinkedHashMap
和 TreeMap
。
这里要注意的是ConcurrentHashMap
不在列表中,因为它允许并发更新,所以它的大小实际上是通话的那一刻。事实上 CHM
甚至没有报告 SIZED
很明显。
然后是与 Map
相关的那些,例如 HashSet
和 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
,所以没有人(据我查看代码)那样做。