8

我错过了一些非常明显的东西吗?还是世界上没有人真正使用 java.util.BitSet?

以下测试失败:

@Test
public void testBitSet() throws Exception {
    BitSet b = new BitSet();
    b.set(0, true);
    b.set(1, false);
    assertEquals(2, b.length());
}

我真的不清楚为什么我没有得到一个长度为 2 和值为 10 的 BitSet。我偷看了 java.util.BitSet 的源代码,在不经意的检查中,它似乎无法充分区分位那已被设置为 false 并且从未设置为任何值的位...

(请注意,在构造函数中显式设置 BitSet 的大小无效,例如:

BitSet b = new BitSet(2);
4

6 回答 6

9

您设置的最高位(如“设置为 1”)是位 0。所以长度应该是 1。

请参阅JavaDoc 了解长度

公共整数长度()

返回此 BitSet 的“逻辑大小”:BitSet 中最高设置位的索引加一。如果 BitSet 不包含设置位,则返回零。

也许您正在寻找大小,尽管如果以特定分辨率(比如 16 位边界)分配位,可能会高于2?

于 2010-05-18T01:43:36.987 回答
6

人们确实使用BitSet; 但是,他们将其用于您想要的其他用途。最好将其BitSet视为一种非常紧凑、节省内存的形式,Set<Integer>它具有不能将负数放入其中的特殊属性。

BitSet在s 的模式中使用它们是很常见的

for (int id = set.nextSetBit(0); id >= 0; id = set.nextSetBit(id + 1)) {
  // do stuff to a set index
}

在你做了一些事情来填满它们之后。这相当于迭代Set.

于 2010-05-18T02:21:23.557 回答
4

This puzzled me too, not sure of the rationale behind BitSet's current rather unexpected functionality. However since it's not final, we can use some embrace and extend tactics and do the following to get a fixed BitSet with length semantics as expected:

import java.util.BitSet;

/**
 * Variation of BitSet which does NOT interpret the highest bit synonymous with
 * its length.
 *
 * @author casper.bang@gmail.com
 */
public class FixedBitSet extends BitSet{

    int fixedLength;

    public FixedBitSet(int fixedLength){
        super(fixedLength);
        this.fixedLength = fixedLength;
    }

    @Override
    public int length() {
        return fixedLength;
    }
}
于 2010-09-20T21:10:16.417 回答
2

鉴于 bitset 由 long[] 支持,最小大小为 64(因为 1 long 是 64 位)。大小以 64 的倍数递增,并且由于某种原因,当您使用采用 int 的构造函数时,它们没有保持您打算表示的位数。

于 2010-08-28T22:39:41.027 回答
1

// 阿拜丹德卡

import java.util.BitSet;

public class TestBitSet {

    public static void main(String[] args) {

        BitSet bitSet = new BitSet();
        System.out.println("State 0 : " + bitSet.size() + " : " + bitSet.length() );

        bitSet.set(0, true);
        bitSet.set(1, true);
        System.out.println("State 1 : " + bitSet.size() + " : " + bitSet.length() );

        bitSet.set(2, false);
        bitSet.set(3, false);
        System.out.println("State 2 : " + bitSet.size() + " : " + bitSet.length() );

        bitSet.set(4, true);
        System.out.println("State 3 : " + bitSet.size() + " : " + bitSet.length() );

    }
}

一个简单的java程序来显示里面发生了什么。需要注意的几点:

  1. BitSet 有很长的支持

  2. 所有默认值都是假的

  3. 在返回长度时,它返回集合中最高“真”值的索引+1。

下面的输出应该能够自我解释:

State 0 : 64 : 0

State 1 : 64 : 2

State 2 : 64 : 2

State 3 : 64 : 5

所以得出结论:

  1. 不使用长度来推断修改的位数

  2. 可用于布隆过滤器等场景。更多关于布隆过滤器的信息可以google .. ;)

希望这可以帮助

问候,

阿拜丹德卡

于 2014-04-18T06:59:41.887 回答
0

好卡斯帕!您的小改进确实应该存在于原始的 BitSet java def 中!我也建议这个(append() 和 concat() 对各种用途很有用)

import java.util.BitSet;

public class fixBitSet extends BitSet {

  public int fsize = 0;

  public void set(int k, boolean value) {
    if (k >= fsize)
      fsize = k + 1;
    super.set(k, value);
  }

  public void append(fixBitSet bs) {
    for (int k = 0; k < bs.fsize; k++)
      super.set(fsize + k, bs.get(k));
    fsize += bs.fsize;
  }

  public static fixBitSet concat(fixBitSet[] vbs) {
    final fixBitSet bs = new fixBitSet();
    for (fixBitSet xbs : vbs)
      bs.append(xbs);
    return (bs);
  }

}
于 2014-01-22T06:58:26.187 回答