Java 中的非常紧凑的 Bitarray

我正在寻找一种非常紧凑的方式在Java中存储密集可变长度的bitarray。现在,我正在使用 ,但它似乎平均使用1.5 * n位的存储空间来存储大小为n的位向量。通常,这不是问题,但在这种情况下,存储的比特数组是应用程序内存占用量的重要组成部分。所以,让它们变得更小一点真的会有所帮助。BitSet

BitSet 所需的空间似乎是由于用于支持数据结构的 long 数组在每次扩展以容纳更多位时往往会加倍:

// BitSet's resizing code
private void ensureCapacity(int wordsRequired) {
  if (words.length < wordsRequired) {
    // Allocate larger of doubled size or required size
    int request = Math.max(2 * words.length, wordsRequired);
    words = Arrays.copyOf(words, request);
    sizeIsSticky = false;
  }
}

我可以编写自己的 BitSet 替代实现,以更保守的方式扩展后端数据结构。但是,如果没有必要,我真的很讨厌复制标准类库中已经存在的功能。


答案 1

如果使用构造函数创建 ,则可以指定容量。如果您猜错了容量,然后仔细检查,它将使大小增加一倍。BitSetBitSet(int nbits)

该类确实有一个私有方法,由 writeObject 和 clone() 调用。如果克隆对象或序列化对象,则会将其修剪为正确的长度(假设类通过 ensureCapacity 方法过度扩展了它)。BitSettrimToSize


答案 2

您可能会从压缩的 BitSet 替代项中受益。例如,请参阅:

https://github.com/lemire/javaewah

http://roaringbitmap.org/