2012-08-22 30 views
1

在Java中,我有一個數百萬左右的標誌真/假記住。 BitSet應該幫忙嗎?雖然它實現了Set,但它是否可以像它的數組boolean[]一樣快地迭代它的元素?長Java位列表想要

對不起,如果問題已被問到。首先,我嘗試將一個數組分割成二進制表示的int,並由於這些二進制形式而形成int[],所以我可以將大小減小32,但這是相當低級的。

我在其他地方發現了一些批評者BitSet,並且boolean[]存儲了大量額外的內存=>對於大型陣列不利。

任何更好的主意存儲一百萬的標誌?

+1

在典型情況下,您是否有多少設置爲true的想法?如果標誌幾乎總是假,一個簡單的'HashSet'或者'TreeSet'將比'BitSet'或'boolean []'少得多的內存。 –

回答

2

我有一百萬左右的國旗真/假記住存儲陣列。 BitSet應該有幫助嗎?

您可以在BitSet中擁有數十億位。

儘管它實現了一個Set,它是否可以迭代它的元素,就像它是一個數組boolean []一樣快?

boolean []每位使用一個字節(在大多數JVM上),而BitSet每位使用一位。對於小型數組,布爾型[]更快,但是當您測試CPU高速緩存的大小時,BitSet可以更高效。

順便說一句:使用BitSet對於小尺寸稍微慢一些,因爲它需要從每個內存字中提取出一點。 A byte[]有同樣的問題,所以如果你想自己設置位,我建議你使用像BitSet那樣的int[]


使用的BitSet

BitSet bitSet = new BitSet(); 
// set bit 100 
bitSet.set(100); 
// get bit 99 
System.out.println("bit 99 is " + bitSet.get(99)); 
System.out.println("bit 100 is " + bitSet.get(100) + " after set"); 
bitSet.clear(100); 
System.out.println("bit 100 is " + bitSet.get(100) + " after clear"); 

打印

bit 99 is false 
bit 100 is true after set 
bit 100 is false after clear 
+0

我用'int []'做了一個預先指定的大小,它的工作速度比'boolean []'快。使用'BitSet'我不明白如何添加元素:)並找不到一個好的網頁來閱讀它的屬性。所以我的選擇是'int []',希望它比'BitSet'更快。 –

+0

@SophieSperner它可能是相同的速度,除了一個BitSet更簡單。要設置你調用set(n)的第n個位並得到你使用get(n)的第n個位,或許你認爲它比它更復雜。 ;) –

+0

@SophieSperner我已經添加了一個例子。 –

0

http://docs.oracle.com/javase/tutorial/java/nutsandbolts/datatypes.html

  • 布爾:布爾數據類型只有兩個可能的值:真和假 。將此數據類型用於跟蹤真/假 條件的簡單標誌。這種數據類型代表了一點信息,但其「尺寸」不是精確定義的。

如果您擔心的是規模和可預測性,那麼我會試圖將8位塊表示爲字節,然後存儲在一個字節[]中。

1

我會用一個簡單的boolean[]。 另外,請注意BitSet未實現Set接口。

public class BitSet implements Cloneable, java.io.Serializable 
1

只是一個想法,怎麼樣使用的東西像HashSet,並補充說,是 「上」 標誌的索引的例子,當它們「關閉」時將它們移除。

(如果大多數標誌在任何給定的時間都關閉,這將工作得特別好)。

+0

只要主要是一種方式或另一種方式,這可能是一個很好的解決方案。如果它是一個很好的組合,那麼你會從現在開始使用更多的內存,而不是集合中的bit或boolean,它將是Integer。 – digitaljoel

+0

@digitaljoel是的,天真地說,像「32:1」這樣的比例會使內存成爲一個「好」的解決方案。 – NominSim

0

BitSet操作非常高效,您可以自己檢查the sources。它沒有實現Set,但你可以在各個位有效迭代在一個簡單的循環,如:

int l = bitSet.length(); 
for(int i = 0; i < l; i++) { 
    boolean bit = bitSet.get(i); 
    // ... 
} 

(上`BitSet1你有沒有發現什麼批評,請在你的問題的鏈接給別人看? 。)


如果你有一個固定的一套你需要管理布爾標誌,你可以在enum列出它們,然後用EnumSet代表標誌設置。對它們的操作也非常有效。引用文檔:

該類的空間和時間性能應該足夠好,可以用作傳統基於int的「位標誌」的高質量類型安全替代方案。即使批量操作(如containsAll和retainAll)也應該運行得非常快,如果它們的參數也是一個枚舉集合。

而作爲一個額外的好處相比BitSet S,這表示是type-safe,它可以爲你節省很多的麻煩。