標籤:color 操作 初始 ISE 索引 cts 預設 沒有 儲存空間
原理簡介:
Java平台的BitSet用於存放一個位序列,如果要高效的存放一個位序列,就可以使用位集(BitSet)。由於位集將位封裝在位元組裡,所以使用位集比使用Boolean對象的List更加高效和更加節省儲存空間。
BitSet是位操作的對象,值只有0或1即false和true,內部維護了一個long數組,初始只有一個long,所以BitSet最小的size是64,當隨著儲存的元素越來越多,BitSet內部會動態擴充,一次擴充64位,最終內部是由N個long來儲存。
預設情況下,BitSet的所有位都是false即0。
在沒有外部同步的情況下,多個線程操作一個BitSet是不安全的。
一個1GB的空間,有8*1024*1024*1024 = 8.58*10^9bit,也就是1GB的空間可以表示85億多個數。
應用情境:
1. 統計一組大資料中沒有出現過的數;
將這組資料對應到BitSet,然後遍曆BitSet,對應位為0的數表示沒有出現過的資料。
2. 對大資料進行排序;
將資料對應到BitSet,遍曆BitSet得到的就是有序資料。
3. 在記憶體對大資料進行壓縮儲存等等。
一個GB的記憶體空間可以儲存85億多個數,可以有效實現資料的壓縮儲存,節省記憶體空間開銷。
為什麼BitSet使用long數組做內部儲存?
JDK選擇long數組作為BitSet的內部儲存結構是出於效能的考慮,因為BitSet提供and和or這種操作,需要對兩個BitSet中的所有bit位做and或者or,實現的時候需要遍曆所有的數組元素。使用long能夠使得迴圈的次數降到最低,所以Java選擇使用long數組作為BitSet的內部儲存結構。
從資料在棧上的儲存來說,使用long和byte基本是沒有什麼差別的,除了編譯器強制地址對齊的時候,使用byte最多會浪費7個位元組(強制按照8的倍數做地址對其),另外從記憶體讀數組元素的時候,也是沒有什麼區別的,因為彙編指令有對不同長度資料的mov指令。所以說,JDK選擇使用long數組作為BitSet的內部儲存結構的根本原因就是在and和or的時候減少迴圈次數,提高效能。
例如我們進行BitSet中的and, or,xor操作時,要對整個bitset中的bit都進行操作,需要依次讀出bitset中所有的word,如果是long數組儲存,我們可以每次讀入64個bit,而int數組儲存時,只能每次讀入32個bit。另外我們在尋找bitset中下一個置為1的bit時,word首先會和0進行比較,如果word的值為0,則表示該word中沒有為1的bit,可以忽略這個word,如果是long數組儲存,可以一次跳過64個bit,如果是int數組儲存時,一次只能跳過32個bit。
(本段來源:知乎 http://www.zhihu.com/question/21061816)
BitSet API
BitSet() 建立一個新的位 set。 |
BitSet(int nbits) 建立一個位 set,它的初始大小足以顯式表示索引範圍在 0 到 nbits-1 的位。 |
void |
and(BitSet set) 對此目標位 set 和參數位 set 執行邏輯與操作。 |
void |
andNot(BitSet set) 清除此 BitSet 中所有的位,其相應的位在指定的 BitSet 中已設定。 |
int |
cardinality() 返回此 BitSet 中設定為 true 的位元。 |
void |
clear() 將此 BitSet 中的所有位設定為 false。 |
void |
clear(int bitIndex) 將索引指定處的位設定為 false。 |
void |
clear(int fromIndex, int toIndex) 將指定的 fromIndex(包括)到指定的 toIndex(不包括)範圍內的位設定為 false。 |
Object |
clone() 複製此 BitSet,產生一個與之相等的新 BitSet。 |
boolean |
equals(Object obj) 將此對象與指定的對象進行比較。 |
void |
flip(int bitIndex) 將指定索引處的位設定為其當前值的補碼。 |
void |
flip(int fromIndex, int toIndex) 將指定的 fromIndex(包括)到指定的 toIndex(不包括)範圍內的每個位設定為其當前值的補碼。 |
boolean |
get(int bitIndex) 返回指定索引處的位值。 |
BitSet |
get(int fromIndex, int toIndex) 返回一個新的 BitSet,它由此 BitSet 中從 fromIndex(包括)到 toIndex(不包括)範圍內的位組成。 |
int |
hashCode() 返回此位 set 的雜湊碼值。 |
boolean |
intersects(BitSet set) 如果指定的 BitSet 中有設定為 true 的位,並且在此 BitSet 中也將其設定為true,則返回 ture。 |
boolean |
isEmpty() 如果此 BitSet 中沒有包含任何設定為 true 的位,則返回 ture。 |
int |
length() 返回此 BitSet 的“邏輯大小”:BitSet 中最高設定位的索引加 1。 |
int |
nextClearBit(int fromIndex) 返回第一個設定為 false 的位的索引,這發生在指定的起始索引或之後的索引上。 |
int |
nextSetBit(int fromIndex) 返回第一個設定為 true 的位的索引,這發生在指定的起始索引或之後的索引上。 |
void |
or(BitSet set) 對此位 set 和位 set 參數執行邏輯或操作。 |
void |
set(int bitIndex) 將指定索引處的位設定為 true。 |
void |
set(int bitIndex, boolean value) 將指定索引處的位設定為指定的值。 |
void |
set(int fromIndex, int toIndex) 將指定的 fromIndex(包括)到指定的 toIndex(不包括)範圍內的位設定為 true。 |
void |
set(int fromIndex, int toIndex, boolean value) 將指定的 fromIndex(包括)到指定的 toIndex(不包括)範圍內的位設定為指定的值。 |
int |
size() 返回此 BitSet 表示位值時實際使用空間的位元。 |
String |
toString() 返回此位 set 的字串表示形式。 |
void |
xor(BitSet set) 對此位 set 和位 set 參數執行邏輯異或操作。 |
Java BitSet(位集)