为啥 BitSet 不可迭代?

Posted

技术标签:

【中文标题】为啥 BitSet 不可迭代?【英文标题】:Why is BitSet not Iterable?为什么 BitSet 不可迭代? 【发布时间】:2017-06-09 20:24:15 【问题描述】:

BitSet 有一个stream() 方法,但它不像提供此方法的其他类型那样实现Iterable 接口。这有什么具体原因吗?

【问题讨论】:

【参考方案1】:

BitSet 中没有提供Iterableforeachiteratorspliterator)中的任何方法。 Iterable 中没有 stream() 方法。

此外,BitSetstream() 方法不会在位集的位上返回流,而是在 其值已设置的位的索引上返回流(即有点令人困惑的TBH)。因此,从技术上讲,这似乎与Iterable 几乎没有任何共同之处。

【讨论】:

【参考方案2】:

一个原因(也许不是全部原因)是Iterable 效率低,因为位索引必须被装箱(*);流能够使用原始整数。

如 Javadoc 中所述,有一种无需使用 Iterable 即可迭代 bitset 的有效方法,因此实际上没有必要。


(*) 但是,对于大小为 128 或更小的位集,装箱会很便宜,因为会使用缓存的装箱实例。

【讨论】:

【参考方案3】:

BitSet 不是 java 集合框架的“真正”成员,所以从技术上讲,不需要实现 Collection.iterator() 并提供一个。

public class BitSet implements Cloneable, java.io.Serializable 

更重要的是,两者都不合适。

BitSet 不是 generic,不像 java.util.Iterator;与 Iterator 不同,BitSet 提供了具有特殊功能的 ad-hoc 方法来处理副作用和随机寻址。

【讨论】:

【参考方案4】:

可能是为了避免将每一位都昂贵地装箱到Boolean 实例。

使用它自己的 API 循环遍历它会避免所有分配。

【讨论】:

我猜可能是一个原始的简短 @fabienbk:不; Java 不支持原始泛型。 装箱到布尔值真的很便宜:只有两个,而且它们被缓存了。 stream 返回代表设置位索引的ints;我认为 OP 期望 Iterable 做同样的事情(Integer 除外)。 哎呀,你是对的。绝对是主要原因。 “有点被遗弃的课程”需要引用。根据我的经验,它并没有被放弃,而是仅用于特定的应用程序。

以上是关于为啥 BitSet 不可迭代?的主要内容,如果未能解决你的问题,请参考以下文章

迭代std :: bitset中真实位的有效方法?

为啥 std::bitset 的位顺序相反? [复制]

为啥 std::bitset<8> 变量无法处理 11111111?

为啥 Java `BitSet` 没有 `shiftLeft` 和 `shiftRight` 函数?

为啥带有 unsigned long long 参数的 std::bitset 构造函数未标记为显式?

为啥Java中BitSet的内部数据存储为long[]而不是Java中的int[]?