为啥 BitSet 不可迭代?
Posted
技术标签:
【中文标题】为啥 BitSet 不可迭代?【英文标题】:Why is BitSet not Iterable?为什么 BitSet 不可迭代? 【发布时间】:2017-06-09 20:24:15 【问题描述】:BitSet
有一个stream()
方法,但它不像提供此方法的其他类型那样实现Iterable
接口。这有什么具体原因吗?
【问题讨论】:
【参考方案1】:BitSet
中没有提供Iterable
(foreach
、iterator
和 spliterator
)中的任何方法。 Iterable
中没有 stream()
方法。
此外,BitSet
的 stream()
方法不会在位集的位上返回流,而是在 其值已设置的位的索引上返回流(即有点令人困惑的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
返回代表设置位索引的int
s;我认为 OP 期望 Iterable
做同样的事情(Integer
除外)。
哎呀,你是对的。绝对是主要原因。
“有点被遗弃的课程”需要引用。根据我的经验,它并没有被放弃,而是仅用于特定的应用程序。以上是关于为啥 BitSet 不可迭代?的主要内容,如果未能解决你的问题,请参考以下文章
为啥 std::bitset<8> 变量无法处理 11111111?
为啥 Java `BitSet` 没有 `shiftLeft` 和 `shiftRight` 函数?