1. 程式人生 > >BitSet的使用場景及簡單示例

BitSet的使用場景及簡單示例

BitSet簡介

    類實現了一個按需增長的位向量。位 set 的每個元件都有一個boolean值。用非負的整數將BitSet的位編入索引。可以對每個編入索引的位進行測試、設定或者清除。通過邏輯與、邏輯或和邏輯異或操作,可以使用一個BitSet修改另一個BitSet的內容。

    預設情況下,set 中所有位的初始值都是false。

    每個位 set 都有一個當前大小,也就是該位 set 當前所用空間的位數。注意,這個大小與位 set 的實現有關,所以它可能隨實現的不同而更改。位 set 的長度與位 set 的邏輯長度有關,並且是與實現無關而定義的。

    除非另行說明,否則將 null 引數傳遞給BitSet中的任何方法都將導致NullPointerException。

    在沒有外部同步的情況下,多個執行緒操作一個BitSet是不安全的

基本原理

    BitSet是位操作的物件,值只有0或1即false和true,內部維護了一個long陣列,初始只有一個long,所以BitSet最小的size是64,當隨著儲存的元素越來越多,BitSet內部會動態擴充,最終內部是由N個long來儲存,這些針對操作都是透明的。

    用1位來表示一個數據是否出現過,0為沒有出現過,1表示出現過。使用用的時候既可根據某一個是否為0表示,此數是否出現過。

    一個1G的空間,有 8*1024*1024*1024=8.58*10^9bit,也就是可以表示85億個不同的數

使用場景

    常見的應用是那些需要對海量資料進行一些統計工作的時候,比如日誌分析、使用者數統計等等

    如統計40億個資料中沒有出現的資料,將40億個不同資料進行排序等。
    現在有1千萬個隨機數,隨機數的範圍在1到1億之間。現在要求寫出一種演算法,將1到1億之間沒有在隨機數中的數求出來

程式碼示例

package util;

import java.util.Arrays;
import java.util.BitSet;

public class BitSetDemo {

	/**
	 * 求一個字串包含的char
	 * 
	 */
	publicstaticvoidcontainChars
(String str)
{ BitSet used = new BitSet(); for (int i = 0; i < str.length(); i++) used.set(str.charAt(i)); // set bit for char StringBuilder sb = new StringBuilder(); sb.append("["); int size = used.size(); System.out.println(size); for (int i = 0; i < size; i++) { if (used.get(i)) { sb.append((char) i); } } sb.append("]"); System.out.println(sb.toString()); } /** * 求素數 有無限個。一個大於1的自然數,如果除了1和它本身外,不能被其他自然數整除(除0以外)的數稱之為素數(質數) 否則稱為合數 */ publicstaticvoidcomputePrime() { BitSet sieve = new BitSet(1024); int size = sieve.size(); for (int i = 2; i < size; i++) sieve.set(i); int finalBit = (int) Math.sqrt(sieve.size()); for (int i = 2; i < finalBit; i++) if (sieve.get(i)) for (int j = 2 * i; j < size; j += i) sieve.clear(j); int counter = 0; for (int i = 1; i < size; i++) { if (sieve.get(i)) { System.out.printf("%5d", i); if (++counter % 15 == 0) System.out.println(); } } System.out.println(); } /** * 進行數字排序 */ publicstaticvoidsortArray() { int[] array = new int[] { 423, 700, 9999, 2323, 356, 6400, 1,2,3,2,2,2,2 }; BitSet bitSet = new BitSet(2 << 13); // 雖然可以自動擴容,但儘量在構造時指定估算大小,預設為64 System.out.println("BitSet size: " + bitSet.size()); for (int i = 0; i < array.length; i++) { bitSet.set(array[i]); } //剔除重複數字後的元素個數 int bitLen=bitSet.cardinality(); //進行排序,即把bit為true的元素複製到另一個數組 int[] orderedArray = new int[bitLen]; int k = 0; for (int i = bitSet.nextSetBit(0); i >= 0; i = bitSet.nextSetBit(i + 1)) { orderedArray[k++] = i; } System.out.println("After ordering: "); for (int i = 0; i < bitLen; i++) { System.out.print(orderedArray[i] + "\t"); } System.out.println("iterate over the true bits in a BitSet"); //或直接迭代BitSet中bit為true的元素iterate over the true bits in a BitSet for (int i = bitSet.nextSetBit(0); i >= 0; i = bitSet.nextSetBit(i + 1)) { System.out.print(i+"\t"); } System.out.println("---------------------------"); } /** * 將BitSet物件轉化為ByteArray * @param bitSet * @return */ publicstaticbyte[] bitSet2ByteArray(BitSet bitSet) { byte[] bytes = new byte[bitSet.size() / 8]; for (int i = 0; i < bitSet.size(); i++) { int index = i / 8; int offset = 7 - i % 8; bytes[index] |= (bitSet.get(i) ? 1 : 0) << offset; } return bytes; } /** * 將ByteArray物件轉化為BitSet * @param bytes * @return */ publicstatic BitSet byteArray2BitSet(byte[] bytes) { BitSet bitSet = new BitSet(bytes.length * 8); int index = 0; for (int i = 0; i < bytes.length; i++) { for (int j = 7; j >= 0; j--) { bitSet.set(index++, (bytes[i] & (1 << j)) >> j == 1 ? true : false); } } return bitSet; } /** * 簡單使用示例 */ publicstaticvoidsimpleExample() { String names[] = { "Java", "Source", "and", "Support" }; BitSet bits = new BitSet(); for (int i = 0, n = names.length; i < n; i++) { if ((names[i].length() % 2) == 0) { bits.set(i); } } System.out.println(bits); System.out.println("Size : " + bits.size()); System.out.println("Length: " + bits.length()); for (int i = 0, n = names.length; i < n; i++) { if (!bits.get(i)) { System.out.println(names[i] + " is odd"); } } BitSet bites = new BitSet(); bites.set(0); bites.set(1); bites.set(2); bites.set(3); bites.andNot(bits); System.out.println(bites); } publicstaticvoidmain(String args[]) { //BitSet使用示例 BitSetDemo.containChars("How do you do? 你好呀"); BitSetDemo.computePrime(); BitSetDemo.sortArray(); BitSetDemo.simpleExample(); //BitSet與Byte陣列互轉示例 BitSet bitSet = new BitSet(); bitSet.set(3, true); bitSet.set(98, true); System.out.println(bitSet.size()+","+bitSet.cardinality()); //將BitSet物件轉成byte陣列 byte[] bytes = BitSetDemo.bitSet2ByteArray(bitSet); System.out.println(Arrays.toString(bytes)); //在將byte陣列轉回來 bitSet = BitSetDemo.byteArray2BitSet(bytes); System.out.println(bitSet.size()+","+bitSet.cardinality()); System.out.println(bitSet.get(3)); System.out.println(bitSet.get(98)); for (int i = bitSet.nextSetBit(0); i >= 0; i = bitSet.nextSetBit(i + 1)) { System.out.print(i+"\t"); } } }

參考:

http://blog.csdn.net/haojun186/article/details/8482343