簡體   English   中英

java.util.BitSet — set()不能按預期工作

[英]java.util.BitSet — set() doesn't work as expected

我是否錯過了明顯痛苦的事情? 還是世界上沒有人真正使用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的BitSet和值為10的結果。我偷看了java.util.BitSet的源代碼,並且在隨意檢查時似乎無法對兩者進行足夠的區分。設置為false,並且從未設置為任何值...

(請注意,在構造函數中顯式設置BitSet的大小無效,例如:

BitSet b = new BitSet(2);

您設置的最高位(如“設置為1”中的位)是位0。因此長度應為1。

有關長度,請參見JavaDoc

public int length()

返回此BitSet的“邏輯大小”:BitSet中最高設置位的索引加1。 如果BitSet不包含任何設置位,則返回零。

也許你正在尋找的大小雖然有可能,如果位在某個分辨率(16說位邊界)分配可能超過兩更高

人們確實使用BitSet ; 但是,他們將其用於其他用途。 最好將BitSet視為Set<Integer>一種非常緊湊的內存有效形式,它具有奇特的屬性,您不能在其中添加負數。

BitSet的模式使用它們在BitSet很常見

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

在您做一些事以填補他們之后。 這等效於迭代Set的元素。

這也讓我感到困惑,不確定BitSet當前相當意外的功能背后的原理。 但是,由於它不是最終的,我們可以使用一些擁抱和擴展策略,並按照預期進行以下操作以獲得具有長度語義的固定BitSet:

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;
    }
}

假設該位集由long []支持,則最小大小為64(因為1 long為64位)。 大小增加了64的倍數,並且由於某種原因,它們沒有維護使用帶int的構造函數時要表示的位數。

// Abhay Dandekar

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. 所有默認值均為false

  3. 返回長度時,它返回集合中最高“ true”值的索引+1。

下面的輸出應該能夠解釋自己:

State 0 : 64 : 0

State 1 : 64 : 2

State 2 : 64 : 2

State 3 : 64 : 5

因此,得出以下結論:

  1. 不要使用長度來推斷修改的位數

  2. 可以在布隆過濾器之類的場景中使用。 更多關於bloom過濾器的信息可以在谷歌上搜索..;)

希望這可以幫助

問候,

阿比·丹德卡(Abhay Dandekar)

好卡斯珀! 您的小改進確實應該已經存在於原始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);
  }

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM