2010-05-18 68 views
7

我是否錯過了一些顯而易見的東西?或者世界上沒有人真正使用java.util.BitSet?java.util.BitSet - set()不能按預期工作

下面的測試失敗:

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

這真是我不清楚我爲什麼不與長度爲2的位集合和值10.我在源java.util.BitSet中偷看結束,並且經常進行檢查,似乎未能對已被設置爲假的位和從未設置爲任何值的位進行足夠的區分...

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

BitSet b = new BitSet(2); 
+1

「抑或只是世界上沒有人實際使用的java.util。位集合?」 ...是的,拉,另一個 - 它有鐘聲! – 2010-05-18 02:13:32

+0

@Stephen哪一個? ;-) – denishaskin 2010-05-18 20:10:56

+1

*其他*另一個! – 2010-05-19 03:42:32

回答

6

人們使用BitSet;然而,他們將它用於除你想要的東西之外的東西。最好將BitSet想象成一個非常緊湊,高效的Set<Integer>形式,它具有您不能將負數放入其中的特性。

這是非常常見的有BitSet是你做的東西來填補起來後使用這些數據在

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

格局。這相當於迭代Set的元素。

+0

很好的解釋。基本上,BitSet似乎並不適合表示固定長度的位域(或位陣列)。 – denishaskin 2010-05-18 20:10:19

+0

那麼,對於一個固定的*長度,如果你不依賴BitSet來保持你的長度,那沒關係。如果你想讓BitSet爲你處理長度,你會感到失望。 – 2010-05-18 22:04:37

8

您最高位設置(如 「設置爲1」)是位0。因此長度應爲1

JavaDoc for length

公衆詮釋長度()

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

也許你正在尋找size雖然它可能的,如果位是在特定分辨率(比如16位邊界)的分配,可能是更高不是兩個?

+0

ZZ,我把它清理乾淨,確保它清楚(併爲它+1),希望你不要介意。鑑於我最初誤解「設置」爲「已被設置爲任何東西」,較小的凡人可能也有這個問題:-) – paxdiablo 2010-05-18 01:50:55

+0

@paxdiablo:更清楚。謝謝! – 2010-05-18 01:58:57

2

考慮到bitset由long []支持,最小大小爲64(因爲1 long是64位)。大小增加了64的倍數,出於某種原因,當你使用帶int的構造函數時,它們並沒有保留你想表示的位數。

3

這讓我很困惑,不確定BitSet目前相當意想不到的功能背後的基本原理。但是因爲它不是最終的,我們可以使用一些擁抱和擴展的策略並執行以下操作來獲得一個固定的BitSet與長度語義預期:

import java.util.BitSet; 

/** 
* Variation of BitSet which does NOT interpret the highest bit synonymous with 
* its length. 
* 
* @author [email protected] 
*/ 
public class FixedBitSet extends BitSet{ 

    int fixedLength; 

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

    @Override 
    public int length() { 
     return fixedLength; 
    } 
} 
0

良好卡斯珀!你的小改進應該已經存在於原始的BitSet java def!我也建議這個(追加()和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); 
    } 

} 
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. 位集合由長

  2. 所有默認值的支持是假

  3. 在返回的長度,它返回指數+的最高「真1 「在集合中的價值。

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

State 0 : 64 : 0 

State 1 : 64 : 2 

State 2 : 64 : 2 

State 3 : 64 : 5 

那麼點得出結論:

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

  2. 可用於布隆過濾器等場景。更多關於布隆過濾器可以用Google搜索..;)

希望這有助於

問候,

阿沛丹德卡爾