为什么Java“BitSet”没有“shiftLeft”和“shiftRight”函数



缺少这些有什么特殊原因吗?

它们确实存在于BigInteger中,但由于BigInteger的不可变设计模式,它们通常非常慢。BitSet要好得多,因为它是可变的,但我真的很怀念shift函数(long s的<<>>>)。对于BitSet,原位移位以及循环旋转也将是有用的。

我看到了对移位Java位集的回复(使用get(off, len)进行移位;但是这需要复制)。

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

从概念上讲,BitSet通常/经常用于跟踪许多设置,因此集合中的每个位都有特定的含义。因此,在这种情况下,轮班操作没有什么意义。

很明显,您已经为BitSet找到了另一个有用的用途,但它超出了BitSet可能设想的范围。

我的猜测是,这会使他们的一些代码变得更加复杂。例如,如果你把所有的东西都"左移3",你可以有一个额外的字段,shift,它是-3(或者可能是3,我只有50%的机会做对:-)。而且,对于get()和set()方法,如果您只是通过shift来调整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(),代码会变得非常混乱。现在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。显然<lt;循环,现在我记得我遥远的机器语言,这是有道理的。

最新更新