有效地迭代Java中的大量位数组中的未设置值

时间:2015-02-26 21:02:12

标签: java bitarray iterate

我将一个大量的数组保存为字节数组,表示所有已签名的int值(4,294,967,295)。

byte[] bitArray = byte[536870912];

数组中的每个字节代表8个数字,每个位一个。这意味着byte [0]存储1,2,3,4,5,6,7,8和byte [1]存储9,10,11,12,13,14,15,16等。

我用它来存储一个巨大的表,我可以将数字设置为true或false(0或1)。我有一些相当有效的方法来检查是否设置了一个位并设置了一个位(仅使用按位运算符)。

现在我需要一遍又一遍地迭代这个表来找到设置为0的位。当然,只存储我想要迭代的数字会非常有效,所以我不需要每次都检查它们,但是有很多数字将它们存储在ArrayList中会占用大量内存。

如何在位数组中的未设置值上多次有效迭代?

1 个答案:

答案 0 :(得分:4)

  

如何有效地迭代此位数组?

一种方法是使用BitSet。这将同时扫描long[]检查64位,但它的基础方法变成了内在函数。即单机代码指令,可能比你用Java编写的任何东西都要快。

如果您真的想自己编写,我建议您查看BitSet的工作原理并复制它的代码。 (或使用BitSet)

我建议您查看方法numberOfLeadingZeros(long) numberOfTrailingZeros(long) bitCount(long)

内在是JVM"识别"并替换为专门的机器代码指令这可以比复制代码和在Java中运行相同的代码快得多。

  

如何在位数组中的未设置值上多次有效迭代?

在BitSet中,它使用以下循环

public int nextSetBit(int fromIndex) {
    if (fromIndex < 0)
        throw new IndexOutOfBoundsException("fromIndex < 0: " + fromIndex);

    checkInvariants();

    int u = wordIndex(fromIndex);
    if (u >= wordsInUse)
        return -1;

    long word = words[u] & (WORD_MASK << fromIndex);

    while (true) {
        if (word != 0)
            return (u * BITS_PER_WORD) + Long.numberOfTrailingZeros(word);
        if (++u == wordsInUse)
            return -1;
        word = words[u];
    }
}

注意:这是在每次迭代中检查64位。