日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

JDK源码 - BitSet的实现

發布時間:2023/12/18 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 JDK源码 - BitSet的实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

java.util.BitSet是個很有趣的類,了解其內部實現對正確的使用非常重要。?

對象構造:?

Java代碼??
  • private?final?static?int?ADDRESS_BITS_PER_WORD?=?6;??
  • private?final?static?int?BITS_PER_WORD?=?1?<<?ADDRESS_BITS_PER_WORD;??
  • private?long[]?words;??
  • ??
  • private?static?int?wordIndex(int?bitIndex)?{??
  • ????return?bitIndex?>>?ADDRESS_BITS_PER_WORD;??
  • }??
  • ??
  • private?void?initWords(int?nbits)?{??
  • ????words?=?new?long[wordIndex(nbits-1)?+?1];??
  • }??
  • ??
  • public?BitSet()?{??
  • ????initWords(BITS_PER_WORD);??
  • ????...??
  • }??
  • ??
  • public?BitSet(int?nbits)?{??
  • ????...??
  • ????initWords(nbits);??
  • ????...??
  • }??


  • 從貼出來的代碼可以看出,long[] words這個數組是BitSet內部的關鍵實現,如果用戶在構造函數中輸入一個nbits變量,initWords方法會把這個數減1再右移6位加1,按照這個長度產生words數組的長度。?
    如果是輸入的28,那么words的長度是1,?
    如果是輸入的2^6?????? = 64,那么words的長度是1,?
    如果是輸入的2^6+1???? = 65,那么words的長度是2,?
    如果是輸入的(2^6)*2?? = 128,那么words的長度是2,?
    如果是輸入的(2^6)*2+1 = 129,那么words的長度是3,?
    如果是輸入的(2^6)*3?? = 192,那么words的長度是3,?
    如果是輸入的(2^6)*3+1 = 193,那么words的長度是4,?
    ...?

    到這里已經很清楚了,BitSet用long類型表示“位圖”,因為一個long是64bit,所以每個long表示64個數據,也就是說:數組中words中的第一個long表示0~63,第二個long表示64~127,第三個long表示128~191 ...?

    再看看get函數,檢測某個數是否被置位:?

    Java代碼??
  • public?boolean?get(int?bitIndex)?{??
  • ????if?(bitIndex?<?0)??
  • ????????throw?new?IndexOutOfBoundsException("bitIndex?<?0:?"?+?bitIndex);??
  • ...??
  • ????int?wordIndex?=?wordIndex(bitIndex);??
  • ????return?(wordIndex?<?wordsInUse)??
  • ????????&&?((words[wordIndex]?&?(1L?<<?bitIndex))?!=?0);??
  • }??

  • 說明:?
    - wordsInUse變量主要用來控制long的容量,當set的數值過大時,BitSet類可以擴充words數組的長度,這一點和很多集合類(例如ArrayList,HashMap)是相似的?
    - 下面的語句值得注意:?
    1L << bitIndex?
    一般看到這條語句,會認為bitIndex如果超過64位,高位會溢出并得到返回0,事實上這個1會重新循環到低位,也就是說:?
    1L << 64 返回為1。?
    術語上這叫循環左移,經過檢測java同樣支持循環右移,運行下面的測試:?

    Java代碼??
  • for?(int?i?=?0;i?<?70?;i++)??
  • ????System.out.println(i?+?"?="?+?(1?>>?i));??

  • 在i為0,32,64時,(1 >> i)重新為1,搞位運算編程的需要注意這個陷阱。?

    注: 經過仔細考慮和試驗,這里不是循環左移和循環右移,是一種比較“奇怪”的實現,回頭寫寫這個問題。?

    BitSet類的一個缺陷:?
    size方法屬于類的內部實現細節,導出成公有方法會讓不了解實現細節的開發人員很迷惑。?

    Java代碼??
  • public?int?size()?{??
  • ????return?words.length?*?BITS_PER_WORD;??
  • }??


  • 例如: 開發人員可能通過bitset.set(100)設置位,然后調用bitset.size(),如果不了解細節,很難理解為什么結果為128。?

    另外,如果實現位域(bit fields),應該考慮使用EnumSet,這一點可以參考Effective Java。

    轉載于:https://www.cnblogs.com/litaobupt/articles/3100070.html

    創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

    總結

    以上是生活随笔為你收集整理的JDK源码 - BitSet的实现的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。