Очень компактный Bitarray в Java

Я ищу очень компактный способ хранения плотной битрейты переменной длины в Java. Прямо сейчас, я использую BitSet, но, кажется, использует в среднем 1.5 * n бит пространства для хранения битового вектора размера n. Как правило, это не проблема, но в этом случае битрейты, которые хранятся, являются довольно значительной частью области памяти приложения. Таким образом, это действительно помогло бы им быть немного меньше.

Пространство, требуемое BitSet, по-видимому, связано с тем, что массив длин, используемый для обратной структуры данных, имеет тенденцию удваиваться каждый раз, когда он расширяется, чтобы содержать больше бит:

// BitSet 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

Если вы создаете BitSet с помощью конструктора BitSet(int nbits), вы можете указать емкость. Если вы угадаете, что емкость неправильная, и перейдите, она удвоит размер.

Класс BitSet имеет метод trimToSize, который является private и вызывается writeObject и clone(). Если вы клонируете свой объект или сериализуете его, он будет обрезать его до нужной длины (предполагая, что класс расширил его с помощью метода securityCapacity).