是否有任何特殊原因导致这些缺失?
它们确实存在于BigInteger
中,但由于BigInteger
的不可变设计模式,这些通常非常慢。 BitSet
更好,因为它是可变的,但我真的很想念shift
函数(<<
和>>>
的{{1}}。对于long
,就地移位也是有用的,以及循环旋转。
我看到了对Shifting a Java BitSet的回复(使用BitSet
进行转移;但这需要复制)。
别误会我的意思。我知道在哪里报告错误。我只是想知道是否有一个特定的原因来省略它们,例如一些设计模式或这样的概念。特别是因为它们 包含在get(off, len)
。
答案 0 :(得分:9)
从概念上讲,BitSet
通常/经常用于跟踪大量设置,因此集合中的每个位都具有特定含义。因此,在这种背景下,轮班操作毫无意义。
您已明确找到BitSet
的另一个有用目的,但它超出了BitSet
可能设想的范围。
答案 1 :(得分:1)
我的猜测是,它会让一些代码变得更复杂。例如,如果你“向左移3”所有东西,你可以有一个额外的字段,移位,即-3(或者3,我只有50%的几率使它正确:-)。并且,对于get()和set()方法,如果您只是按shift调整bitIndex,则代码应该有效。 e.g。
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(),代码会开始变得非常混乱。现在,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);
如果两个BitSets都有可能的转换,这将很快变得混乱。他们可能认为如果你真的想转移,你应该使用get和copy。
有一件事让我感到惊讶 - 在get()中,他们没有做1L << bitIndex&31
。显然&lt;&lt;循环,现在,我记得我的远程机器语言,这是有道理的。