Java位運算工具類-BitSet詳細介紹


BitSet

前言

最近用到了位圖索引的相關知識,第一次接觸Java中進行位向量運算的工具類BitSet,簡單學習記錄一下。

一、簡介

功能

BitSet類是一種用來保存位值的特殊數組,數組的大小可以改變。它和位向量的功能類似。

實現原理

源碼中的介紹如下:

BitSets are packed into arrays of "words." Currently a word is a long, which consists of 64 bits, requiring 6 address bits.The choice of word size is determined purely by performance concerns.

簡言之:

BitSet的數據封裝到一個叫words的數組中,數組中的每一個word都是一個long類型的數據(我的理解是:位向量需要表示為人最容易理解的形式-整數,而表示整數的數據類型中,long的長度最長,為8字節64bit,64bit可以表示64種事物的狀態)

words = new long[wordIndex(nbits-1) + 1];

二、方法

BitSet類的兩種構造方法

  1. 無參構造

    BitSet bs3 = new BitSet();
    

    默認長度為1;

  2. 有參構造

    BitSet bs1 = new BitSet(4);
    

常用方法

  1. length() 返回BitSet的邏輯長度

    BitSet bs1 = new BitSet(4);
    System.out.println(bs3.length());
    bs3.set(2);
    System.out.println(bs3.length());
    

    輸出為:0和3

    輸出為0是因為:bs1的各個位均為false,即0000,所以邏輯長度為0

    輸出為3是因為:bs1變為0010,所以邏輯長度為3

  2. get(i) 獲得i位置的位符號(true or false)

    for (int i = 0; i <4 ; i++) {
        if (i%2 == 0)
            bs1.set(i);//把i位置設為true
    }
    for (int i = 0; i <4 ; i++) {
        if(bs1.get(i)){
            System.out.print("1");
        }
        if(!bs1.get(i)) {
            System.out.print("0");
        }
    }
    

    輸出為:1010

    注:i可以取大於0的任何整數值,但不能取小於0的值;即get(-1)會報錯。

  3. println(s1): 輸出bs1中為true的位所在的索引

    輸出為:{0, 2}
    
  4. and(bs2)

    bs1.and(bs2);
    輸出為:
    ====qian==   
    bs1:1010
    bs2:0110
    ====hou==
    bs1:0010
    bs2:0110
    
  5. andNot(bs1):bs1中0和2所在的位為1,則將bs2中0和1所在的位設置為0;

    bs2.andNot(bs1);
    輸出為:
    ====qian==  
    bs1:1010
    bs2:0110
    ====and==
    bs1:1010
    bs2:0100
    
  6. or:或操作

  7. xor:異或操作;不同取1,相同取0

  8. int cardinality( ):返回BitSet 中設置為 true 的位數。

    System.out.println(bs1.cardinality());輸出為2;
    
  9. clear(int index);clear();clear(int startIndex, int endIndex):將true變成false

  10. BitSet get(int startIndex, int endIndex):返回一個新的BitSet ,長度為endIndex-startIndex

    bs2:0110BitSet bitSet = bs2.get(1, 3);輸出:11
    
  11. boolean intersects(BitSet bitSet):判斷兩個BitSet 中true所在的位置是否相等;二者的長度不限制

  12. int nextSetBit(int startIndex):從startIndex開始,第一個出現true的位置

    bs1:1010System.out.println(bs1.nextSetBit(1));System.out.println(bs1.nextSetBit(0));輸出為:20
    
  13. int size( ):Returns the number of bits of space actually in use by this {@code BitSet} to represent bit values.

    BitSet bs2 = new BitSet(63);BitSet bs3 = new BitSet(65);System.out.println(bs2.size());System.out.println(bs3.size());輸出為:64128
    

    即:BitSet的空間實際使用的單位為64bit

三、補充說明

  • 情況1

    BitSet bs1 = new BitSet(6);BitSet bs2 = new BitSet(63);System.out.println(bs1.length());for (int i = 0; i <63 ; i++) {    if (i%2 == 0)        bs1.set(i);//把i位置設為true}for (int i = 0; i <2 ; i++) {    bs2.set(i);//把i位置設為true}bs2.xor(bs1);System.out.println(bs1.size());System.out.println(bs2.size());
    

    輸出為:64 和 64(因為bs1和bs2賦值的時候,長度都沒有超過64)

  • 情況2

    BitSet bs1 = new BitSet(6);BitSet bs2 = new BitSet(63);System.out.println(bs1.length());for (int i = 0; i <65 ; i++) {    if (i%2 == 0)        bs1.set(i);//把i位置設為true}for (int i = 0; i <2 ; i++) {    bs2.set(i);//把i位置設為true}bs2.xor(bs1);System.out.println(bs1.size());System.out.println(bs2.size());
    

    輸出為:128 和 128(因為bs1賦值的時候長度超過64,並且和bs1進行了位運算,所以長度都變成了128)

    如果把bs2.xor(bs1);去掉,輸出結果為128和64

四、總結

  • BitSet底層是用long類型的數據進行存儲的,且長度單位為64,比如需要表示001,則實際001 = 00100...0(64位)
  • 當長度超過64位時,比如需要表示0010000..0(68位),會用兩個long類型的數據表示該BitSet,即實際的001000..00(68位) = [001000..0(64位),000000000(64位)]
  • 當兩個長度不同的BitSet進行運算時,比如001(3位)和0010000..0(68位)進行運算,最終它們的長度均為68位,實際占有空間的大小為128bit。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM