1

在 Java 中,我有一个包含一百万个左右标志真/假的数组来存储。应该BitSet帮忙吗?尽管它实现了 a Set,但是否可以像数组一样快速地迭代它的元素boolean[]

抱歉,如果问题已被问到。首先,我尝试将数组拆分为二进制表示的整数块,并int[]作为这些二进制文件的结果形成,因此我可以将大小减少 32,但这是相当低级的。

BitSet我发现了其他地方的一些批评者,它们boolean[]存储了大量额外的内存 => 对大型数组不利。

存储一百万个标志有更好的主意吗?

4

5 回答 5

3

我有一百万个左右标志真/假的数组要记住。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
于 2012-08-22T19:05:56.560 回答
1

我会使用一个简单的boolean[]. 另外,请注意BitSet不实现Set接口。

public class BitSet implements Cloneable, java.io.Serializable
于 2012-08-22T19:05:21.177 回答
1

只是一个想法,如何使用类似 aHashSet并添加“打开”标志的索引,当它们“关闭”时将其删除。

(如果您的大多数标志在任何给定时间都关闭,这将特别有效)。

于 2012-08-22T19:09:38.683 回答
0

来自http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

  • boolean:布尔数据类型只有两个可能的值:true 和 false。将此数据类型用于跟踪真/假条件的简单标志。这种数据类型代表一点信息,但它的“大小”并不是精确定义的。

如果您担心大小和可预测性,那么我会考虑尝试将 8 位块表示为字节,然后存储在 byte[] 中。

于 2012-08-22T19:02:06.160 回答
0

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)也应该运行得非常快。

BitSets 相比,作为一个额外的好处,这种表示是类型安全的,可以为您省去很多麻烦。

于 2012-08-22T19:14:40.203 回答