JDK源码 - BitSet的实现
java.util.BitSet是個很有趣的類,了解其內部實現對正確的使用非常重要。?
對象構造:?
從貼出來的代碼可以看出,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函數,檢測某個數是否被置位:?
說明:?
- wordsInUse變量主要用來控制long的容量,當set的數值過大時,BitSet類可以擴充words數組的長度,這一點和很多集合類(例如ArrayList,HashMap)是相似的?
- 下面的語句值得注意:?
1L << bitIndex?
一般看到這條語句,會認為bitIndex如果超過64位,高位會溢出并得到返回0,事實上這個1會重新循環到低位,也就是說:?
1L << 64 返回為1。?
術語上這叫循環左移,經過檢測java同樣支持循環右移,運行下面的測試:?
在i為0,32,64時,(1 >> i)重新為1,搞位運算編程的需要注意這個陷阱。?
注: 經過仔細考慮和試驗,這里不是循環左移和循環右移,是一種比較“奇怪”的實現,回頭寫寫這個問題。?
BitSet類的一個缺陷:?
size方法屬于類的內部實現細節,導出成公有方法會讓不了解實現細節的開發人員很迷惑。?
例如: 開發人員可能通過bitset.set(100)設置位,然后調用bitset.size(),如果不了解細節,很難理解為什么結果為128。?
另外,如果實現位域(bit fields),應該考慮使用EnumSet,這一點可以參考Effective Java。
轉載于:https://www.cnblogs.com/litaobupt/articles/3100070.html
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的JDK源码 - BitSet的实现的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 当同时使用bootstrap-datep
- 下一篇: EOJ Monthly 2019.2 (