为什么Java`BitSet`没有`shiftLeft`和`shiftRight`函数?

时间:2012-02-01 18:47:49

标签: java bitset bit-shift

是否有任何特殊原因导致这些缺失?

它们确实存在于BigInteger中,但由于BigInteger的不可变设计模式,这些通常非常慢。 BitSet更好,因为它是可变的,但我真的很想念shift函数(<<>>>的{​​{1}}。对于long,就地移位也是有用的,以及循环旋转。

我看到了对Shifting a Java BitSet的回复(使用BitSet进行转移;但这需要复制)。

别误会我的意思。我知道在哪里报告错误。我只是想知道是否有一个特定的原因来省略它们,例如一些设计模式或这样的概念。特别是因为它们 包含在get(off, len)

2 个答案:

答案 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;循环,现在,我记得我的远程机器语言,这是有道理的。