将布尔标志与每个可能的整数值相关联的最快方法是什么?

时间:2014-09-17 16:40:25

标签: java performance algorithm data-structures real-time

如果我有一个字节而不是一个整数,我可以很容易地创建一个256位的布尔数组并检查:

boolean[] allBytes = new boolean[256];

if (allBytes[value & 0xFF] == true) {
   // ...
}

因为我有一个整数,所以我不能拥有大小为20亿的数组。检查整数是真还是假的最快方法是什么?一组整数?哈希表?

EDIT1:我想为每个可能的整数(20亿)关联一个真或假标志。

EDIT2:我有ID X(整数),我需要快速了解ID X是ON还是OFF。

3 个答案:

答案 0 :(得分:3)

BitSet无法处理负数。但是有一个简单的方法:

class BigBitSet {
    private final BitSet[] bitSets = new BitSet[] {new BitSet(), new BitSet()};

    public boolean get(int bitIndex) {
        return bitIndex < 0 ? bitSets[1].get(~bitIndex)
                : bitSets[0].get(bitIndex);
    }

    ...
}

第二个BitSet用于负数,它通过'〜'运算符进行翻译(这比仅仅因为它适用于Integer.MIN_VALUE更好)。

内存消耗可能达到4 Gib,即大约524 MB。

答案 1 :(得分:2)

我甚至对此进行详细说明感到愚蠢。

您的计算机可以存储的最小信息单位,对吧?有一个位有两种状态,你想要两种状态,所以我们只说bit = 0为假,bit = 1为真。

所以你需要尽可能多的比特,2 ^ 32 = 4,294,967,296。您可以将8位装入一个字节,因此您只需要2 ^ 32/8 = 536,870,912字节。

从容易遵循的代码中解决字节中的每个位...

 byte[] store = new byte[1 << 29]; // 2^29 bytes provide 2^32 bits

 void setBit(int i) {
     int byteIndex = i >>> 3;
     int bitMask = 1 << (i & 7);
     store[byteIndex] |= bitMask;
 }

 boolean testBit(int i) {
     int byteIndex = i >>> 3;
     int bitMask = 1 << (i & 7);
     return (store[byteIndex] & bitMask) != 0;
 }

java.util.BitSet在一个很好的类中提供了几乎相同的premade,只有你可以使用它来存储最多2 ^ 31位,因为它不适用于负位索引。

答案 2 :(得分:1)

由于您使用的是Java,请使用BitSet。它快速而简单。如果你愿意,你也可以使用一个原始long或BigInteger数组,但这正是BitSet的用途。

http://docs.oracle.com/javase/7/docs/api/java/util/BitSet.html