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
2
3
4
5
6
7
8
9
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;}
添加数据。添加数据会
public void set(int bitIndex){
if(bitIndex <0)
- throw new IndexOutOfBoundsException("bitIndex < 0: "+ bitIndex);
//这里执行的是 bitIndex >> 6;
int wordIndex = wordIndex(bitIndex);//看看是否需要扩充。
expandTo(wordIndex);
words[wordIndex]|=(1L<< bitIndex);//Restores invariants
checkInvariants();
}
这里扩展成倍数扩展,没有优化
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 源代码分析
。阅读全文
0 0
- jdk 源码分析(6)java BitSet结构
- jdk 源码分析(1)java hashmap的结构
- jdk 源码分析(4) java Set 结构
- jdk 源码分析(5)java ConcurrentSkipListMap结构
- jdk 源码分析(7)java ReentrantLock结构
- java 中的集合(六) BitSet源码分析
- BitSet数据结构以及jdk中实现源码分析
- BitSet数据结构以及jdk中实现源码分析
- jdk 源码分析(2)java hashtable的结构及hashMap对比
- 源码分析之BitSet
- jdk 源码分析(14)java ThreadLocal
- jdk 源码分析(0) java 源码分析汇总
- jdk 原地分析(3)java ConcurrentHashMap结构分析
- jdk 源码分析(15)java CountDownLatch 源码解析
- jdk 源码分析(16)java CyclicBarrier 源码解析
- java.util.BitSet 分析
- jdk 源码分析(9)java ReentrantReadWriteLock分析
- jdk 源码分析(10)java unsafe 分析
- 解决Web项目因访问URL与Tomcat服务器文件夹相同导致404页面的问题
- 类和对象
- hdu-2056-Rectangles
- Dubbox 构建Restful服务
- python3常用快捷键——将在学习中不断更新
- jdk 源码分析(6)java BitSet结构
- HDU4648 Magic Pen 6 签到
- [转载自知乎——有哪些令人拍案叫绝的算法?] [侵必付] 关于位运算
- 【PAT】【Advanced Level】1037. Magic Coupon (25)
- 其他对象——math
- 背包问题*
- C++ const的用法详解
- Nginx教程-日志配置
- hah