jdk 源码分析(6)java BitSet结构

来源:互联网 发布:还原软件 编辑:程序博客网 时间:2024/05/22 02:27
虽然bitSet取名有set,但确实不是Set的子集
public class BitSet implements Cloneable, java.io.Serializable 
本来想去找个图片,结果没找到,简单点。

如果有一个Set 里面存放了(整数)1,3,4,5,23,23,12,65这些数,如果直接存储需要8×32位 ;
如果采用位图,只需要用两个long整型串联。

 0

 1

 6

 10

 

 

 

 

 

 

 

 

 

一个位置表示这个数的存储。
比如1,第一个long的第2个位为1
比如4,第一个long的第2个位为1
比如65,第二个long的第2个位为1

所以数据存储时x:
long []value
value[x/64] = value [x/64] | 1L<<x
value[x/64] 表示数据将放在第几个long 中, 因为1l 是以64为周期循环移动,会得到具体的存放位置。
x/64 = x>>6

查看Java 的bitSet的源码:
实际存放的位置
private long[] words;
初始长度为1
public BitSet() {    initWords(BITS_PER_WORD);sizeIsSticky = false;}
添加数据。添加数据会
  1. public void set(int bitIndex){
  2. if(bitIndex <0)
  3. throw new IndexOutOfBoundsException("bitIndex < 0: "+ bitIndex);
  4.   //这里执行的是  bitIndex >> 6;
  5.     int wordIndex = wordIndex(bitIndex);
  6.     //看看是否需要扩充。
  7. expandTo(wordIndex);
  8. words[wordIndex]|=(1L<< bitIndex);//Restores invariants
  9. checkInvariants();
  10. }

这里扩展成倍数扩展,没有优化
private void ensureCapacity(int wordsRequired) {    if (words.length < wordsRequired) {        // Allocate larger of doubled size or required sizeint request = Math.max(2 * words.length, wordsRequired);words = Arrays.copyOf(words, request);sizeIsSticky = false;}}

其他几个重要操作:add 直接是long的& ,比单个位操作要快,
public void and(BitSet set) {    if (this == set)        return;    while (wordsInUse > set.wordsInUse)        words[--wordsInUse] = 0;// Perform logical AND on words in commonfor (int i = 0; i < wordsInUse; i++)        words[i] &= set.words[i];recalculateWordsInUse();checkInvariants();}

其他还有xor,or 等。


不管怎么,bitset 初步解决了数据存储问题。但是还有很多优化问题,
比如:1)需要存储的数据只是一个1亿,那么也需要用1亿/64个long表示。
再比如 连续的 1,2,3,4,5,6 。。。1000.. 也需要存储1000/64个整数。

对于第一种 直接用ArrayList 比 bitset 节约空间。
第二种,采用run of length 比较好。比如开始位 1,重复999 . 所以只需要存储,1,999 就可以了,如果还有,
2000-4000 , 可以是,1,999,2000,1999.
每两个为一个对,第一个为开始位置,第二个为重复次数。

还有bitset的空间分配,本直接,很暴力,直接2倍,如果数据量少没有问题,但是如果本身就有1亿了,再double 已经是个问题,所以可以分层优化。



所有的这些缺点在roaringbitmap里详细说明。可以参考我的文章 

roaringbitmap 源代码分析

















原创粉丝点击