java.util.BitSet 分析

系统 1638 0

我们知道bit-map在大数据处理方面有着很大的用途,比如排序,去重等。

JDK 从1.0开始就提供了 java.util.BitSet 来对bit-map的支持。BitSet的set,get操作主要是通过 “位运算” 进行的。

BitSet的核心是一个 long的数组:

  1. /*  
  2.      * BitSets are packed into arrays of "words."  Currently a word is  
  3.      * a long, which consists of 64 bits, requiring 6 address bits.  
  4.      * The choice of word size is determined purely by performance concerns.  
  5.      */   
  6.      private   final   static   int  ADDRESS_BITS_PER_WORD =  6 ;  
  7.      private   final   static   int  BITS_PER_WORD =  1  << ADDRESS_BITS_PER_WORD;  
  8.      private   final   static   int  BIT_INDEX_MASK = BITS_PER_WORD -  1 ;  
  9.   
  10.      /* Used to shift left or right for a partial word mask */   
  11.      private   static   final   long  WORD_MASK = 0xffffffffffffffffL;  
  12.   
  13.      /**  
  14.      * The internal field corresponding to the serialField "bits".  
  15.      */   
  16.      private   long [] words;  
  17.   
  18.      /**  
  19.      * The number of words in the logical size of this BitSet.  
  20.      */   
  21.      private   transient   int  wordsInUse =  0 ;  
  22.   
  23.      /**  
  24.      * Whether the size of "words" is user-specified.  If so, we assume  
  25.      * the user knows what he's doing and try harder to preserve it.  
  26.      */   
  27.      private   transient   boolean  sizeIsSticky =  false ;  

从bit的角度看,words 应该是一个 二维的bit数据, bit [ ] [64] word, 当然 JDK中没有 bit 这个基本的数据类型。但是JDK提供了丰富的位运算符。每个bit 只有两个值 0 和1(ture 和false)。

bit-map的典型应用场景(伪码表示):

有一个 bit数组 bit [ ] bArray = new bit [ 1024 ]。 要对若干非负整数进行排序,例如:{ 2, 5, 78, 58, 11}。使用bit-map的做法是:

  1. bArray[ 2 ] =  1 ;  
  2. bArray[ 5 ] =  1 ;  
  3. bArray[ 78 ] =  1 ;  
  4. bArray[ 58 ] =  1 ;  
  5. bArray[ 11 ] =  1 ;  

然后顺序遍历bArray就行了。

同样对于BitSet的方法一样,只不过要调用它的set方法,源码如下:

  1. /**  
  2.      * Sets the bit at the specified index to {@code true}.  
  3.      *  
  4.      * @param  bitIndex a bit index  
  5.      * @throws IndexOutOfBoundsException if the specified index is negative  
  6.      * @since  JDK1.0  
  7.      */   
  8.      public   void  set( int  bitIndex) {  
  9.          if  (bitIndex <  0 )  
  10.              throw   new  IndexOutOfBoundsException( "bitIndex < 0: "  + bitIndex);  
  11.   
  12.          int  wordIndex = wordIndex(bitIndex);  
  13.         expandTo(wordIndex);  
  14.   
  15.         words[wordIndex] |= (1L << bitIndex);  // Restores invariants   
  16.   
  17.         checkInvariants();  
  18.     }  

如果将 long [ ] words 理解成 bit [ ] [ 64 ] words的话 

第一步,先算出一维(wordIndex(int bitIndex) 方法)

  1. /**  
  2.      * Given a bit index, return word index containing it.  
  3.      */   
  4.      private   static   int  wordIndex( int  bitIndex) {  
  5.          return  bitIndex >> ADDRESS_BITS_PER_WORD;  
  6.     }  

notice: ADDRESS_BITS_PER_WORD = 6.

第二步,使用位运算对对应的bit进行赋值为1, words[ wordIndex ] |= (1L << bitIndex).

BitSet的get方法和Set方法一样,先确定一维,再通过位运算得到二维中对应的值。

是不是感觉很美妙,通过long数组 再加上 位运算 可以模拟出 bit数组。当然,我们也可以使用int数组或者double行数据来构造 bit数组

java.util.BitSet 分析


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论