在 Java 中,我有一个包含一百万个左右标志真/假的数组来存储。应该BitSet
帮忙吗?尽管它实现了 a Set
,但是否可以像数组一样快速地迭代它的元素boolean[]
?
抱歉,如果问题已被问到。首先,我尝试将数组拆分为二进制表示的整数块,并int[]
作为这些二进制文件的结果形成,因此我可以将大小减少 32,但这是相当低级的。
BitSet
我发现了其他地方的一些批评者,它们boolean[]
存储了大量额外的内存 => 对大型数组不利。
存储一百万个标志有更好的主意吗?
我有一百万个左右标志真/假的数组要记住。BitSet 应该有帮助吗?
您可以在 BitSet 中拥有数十亿位。
虽然它实现了一个 Set,但是否可以像数组 boolean[] 一样快速地迭代它的元素?
boolean[] 每位使用一个字节(在大多数 JVM 上),而 BitSet 每位使用一位。对于小型数组,boolean[] 更快,但是当您测试 CPU 缓存的大小时,BitSet 可能更有效。
顺便说一句:对于小尺寸,使用 BitSet 会稍微慢一些,因为它需要从每个内存字中提取一点。Abyte[]
有同样的问题,所以如果你想自己设置位,我建议你使用int[]
像 BitSet 一样的。
使用 BitSet 的示例
BitSet bitSet = new BitSet();
// set bit 100
bitSet.set(100);
// get bit 99
System.out.println("bit 99 is " + bitSet.get(99));
System.out.println("bit 100 is " + bitSet.get(100) + " after set");
bitSet.clear(100);
System.out.println("bit 100 is " + bitSet.get(100) + " after clear");
印刷
bit 99 is false
bit 100 is true after set
bit 100 is false after clear
我会使用一个简单的boolean[]
. 另外,请注意BitSet
不实现Set
接口。
public class BitSet implements Cloneable, java.io.Serializable
只是一个想法,如何使用类似 aHashSet
并添加“打开”标志的索引,当它们“关闭”时将其删除。
(如果您的大多数标志在任何给定时间都关闭,这将特别有效)。
来自http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html
如果您担心大小和可预测性,那么我会考虑尝试将 8 位块表示为字节,然后存储在 byte[] 中。
BitSet
操作非常有效,您可以自己检查源。它没有实现Set
,但您可以在一个简单的循环中有效地迭代各个位,例如:
int l = bitSet.length();
for(int i = 0; i < l; i++) {
boolean bit = bitSet.get(i);
// ...
}
(您发现了对 `BitSet1 的哪些批评?请在您的问题中包含链接以供其他人查看。)
如果您需要管理一组特定的、固定的布尔标志,您可以将它们列在 an 中enum
,然后使用EnumSet表示标志设置。对它们的操作也非常有效地实施。引用文档:
这个类的空间和时间性能应该足够好,以允许它用作传统的基于 int 的“位标志”的高质量、类型安全的替代品。如果参数也是枚举集,即使批量操作(例如 containsAll 和 retainAll)也应该运行得非常快。
与BitSet
s 相比,作为一个额外的好处,这种表示是类型安全的,可以为您省去很多麻烦。