【问题标题】:Spliterator - sized vs subsized flagsSpliterator - 大小与子大小的标志
【发布时间】:2017-11-04 01:37:14
【问题描述】:

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

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

SUBSIZED 表示所有 Spliterators 的特征值 trySplit() 产生的结果将是 SIZED 和 SUBSIZED。

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

【问题讨论】:

    标签: java java-8 java-stream spliterator


    【解决方案1】:

    Spliterator 的典型示例是SIZED 但不是SUBSIZED,是从HashMap 创建的Spliterator。它将维护其内部条目数组的范围,其中一些数组条目为null,因为容量高于实际大小。要跳过的 null 条目的确切分布取决于所包含键的哈希码。

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

    在没有SIZED 的情况下报告SUBSIZED 特征是没有意义的,据我所知,它甚至无效。

    【讨论】:

    • 在 HashMap 中,如果我不知道有多少值等于 null,那么 SIZED 标志是如何打开的?
    • HashMap 始终保持其大小,这是一个简单的 int 变量。所以它确实知道有多少 null 值存在;这是容量(数组长度)和size 之间的差异,但它不知道它们是如何分布在数组中的。
    • @Holger 如果它的内部数组被拆分,我猜碰撞也会使子大小未知,对吧?例如,第一个桶可能有 3 个条目,而其他桶有 0 个或一个。我理解正确吗?
    • 谢谢@Holger。一如既往的好答案。
    【解决方案2】:

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

    HashMap(如上所述),以及 IdentityHashMapLinkedHashMapTreeMap

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

    还有一些与Map 相关的,例如HashSetTreeSet,因为在内部这些仍然是地图。

    还有一个在 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,所以没有人(据我查看代码)这样​​做。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-09-13
      • 2021-02-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-03-12
      • 1970-01-01
      相关资源
      最近更新 更多