如果我有一个字节而不是一个整数,我可以很容易地创建一个256位的布尔数组并检查:
boolean[] allBytes = new boolean[256];
if (allBytes[value & 0xFF] == true) {
// ...
}
因为我有一个整数,所以我不能拥有大小为20亿的数组。检查整数是真还是假的最快方法是什么?一组整数?哈希表?
EDIT1:我想为每个可能的整数(20亿)关联一个真或假标志。
EDIT2:我有ID X(整数),我需要快速了解ID X是ON还是OFF。
答案 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