Подтвердить что ты не робот

Почему Java `BitSet` не имеет функций` shiftLeft` и `shiftRight`?

Есть ли какая-то конкретная причина, по которой они отсутствуют?

Они существуют в BigInteger, но из-за неизменяемого шаблона проектирования BigInteger они обычно ужасно медленны. BitSet гораздо приятнее, потому что он изменчив, но я действительно пропускаю функции shift (<< и >>> для long s). Для BitSet было бы полезно также смещение в месте, а также циклическое вращение.

Я видел ответ Сдвиг Java BitSet (используя get(off, len) для переключения, однако это требует копирования).

Не поймите меня неправильно. Я знаю, где сообщать об ошибках. Мне просто интересно, есть ли какая-то особая причина, чтобы опустить их, например. некоторый дизайн или такая концепция. В частности, поскольку они включены в BigInteger.

4b9b3361

Ответ 1

Концептуально, BitSet обычно/часто используется для отслеживания множества настроек, так что каждый бит в наборе имеет определенное значение. Поэтому операция сдвига в этом контексте мало смысла.

Вы явно нашли другую полезную цель для BitSet, но вне области, для которой BitSet, вероятно, было предусмотрено.

Ответ 2

Я предполагаю, что это сделает некоторые из их кода более сложными. Например, если вы "оставите смену на 3" все, у вас может быть еще одно поле, сдвиг, который равен -3 (или, может быть, 3, у меня есть только 50% шанс исправить это:-). И, для методов get() и set(), если вы просто отрегулируете bitIndex по смене, код должен работать. например.

public boolean get(int bitIndex) {
    bitIndex += shift;  // new code!!!
    if (bitIndex < 0)
        throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);

    checkInvariants();

    int wordIndex = wordIndex(bitIndex);
    return (wordIndex < wordsInUse)
        && ((words[wordIndex] & (1L << bitIndex)) != 0);
    }

Однако для некоторых других операций, таких как intersects() и или(), код начнет становиться действительно беспорядочным. Прямо сейчас ядро ​​метода or() очень просто и быстро:

 // Perform logical OR on words in common
   for (int i = 0; i < wordsInCommon; i++)
      words[i] |= set.words[i];

   // Copy any remaining words
   if (wordsInCommon < set.wordsInUse)
     System.arraycopy(set.words, wordsInCommon,
                  words, wordsInCommon,
              wordsInUse - wordsInCommon);

Если бы у обоих битовых наборов были возможные сдвиги, это быстро стало бы беспорядочным. Вероятно, они полагали, что если вы действительно хотите сменить, вы должны использовать get и copy.

Одна вещь, которая меня удивила - в get() они не делают 1L << bitIndex&31. По-видимому, < петли вокруг, что, когда я помню свой длинный далекий машинный язык, имеет смысл.