Почему Java `BitSet` не имеет функций` shiftLeft` и `shiftRight`?
Есть ли какая-то конкретная причина, по которой они отсутствуют?
Они существуют в BigInteger
, но из-за неизменяемого шаблона проектирования BigInteger
они обычно ужасно медленны. BitSet
гораздо приятнее, потому что он изменчив, но я действительно пропускаю функции shift
(<<
и >>>
для long
s). Для BitSet
было бы полезно также смещение в месте, а также циклическое вращение.
Я видел ответ Сдвиг Java BitSet (используя get(off, len)
для переключения, однако это требует копирования).
Не поймите меня неправильно. Я знаю, где сообщать об ошибках. Мне просто интересно, есть ли какая-то особая причина, чтобы опустить их, например. некоторый дизайн или такая концепция. В частности, поскольку они включены в BigInteger
.
Ответы
Ответ 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
. По-видимому, < петли вокруг, что, когда я помню свой длинный далекий машинный язык, имеет смысл.