上节IntAllocator是对于BitSet的应用,我们来具体学习BitSet源码
-
默认情况下所有bit初始化都是false
-
不能设置null值
-
不是线程安全的,需要外层做同步
-
BitSet实现Cloneable 和 Serializable接口(说明它具有克隆和序列化功能)
-
BitSet被打包成"字"数组,目前一个字是一个long, 由64位组成,需要6个地址位,也就移动1<<6==64

- 二进制表示0或1,long是8byte, 64bit,也就是一个long可以表示64数字是否存在(0或1),那么如果一个long满怎么办,当然使用下一个long值,所有现在对BitSet有直观的印象,它用long表示64个数字,0-63就存第一个long值中
- 如图1,2都是words数组的word元素,一个word表示64个数字是否存在。
- 怎么确定某个值在BitSet的哪里表示呢?,首先需要找到对应word(取模64), 然后找到word对应位(bit)
1、成员变量和常量
| 名称 | 默认值 | 描述 |
|---|---|---|
| int ADDRESS_BITS_PER_WORD | 6 | 地址位6位 |
| int BITS_PER_WORD | 1 << ADDRESS_BITS_PER_WORD | 64 |
| int BIT_INDEX_MASK | BITS_PER_WORD-1 | 63 |
| long WORD_MASK | 0xffffffffffffffffL | -1 (64位全是1) |
| ObjectStreamField[] serialPersistentFields | new ObjectStreamField(“bits”, long[].class) | 此BitSet中的位。第i位存储在位[i/64]中的位位置i%64(其中位位置0表示最低有效位,63表示最高有效位) |
| long[] words | 对应就是bits | |
| transient int wordsInUse | 0 | words在用的length |
| transient boolean sizeIsSticky | false | "单词"的大小是否由用户指定words数量,如果是,就是true,经过一次扩容之后就是false了 |
2、方法
| 方法名 | 描述 | 图示 |
|---|---|---|
| BitSet() | 构造方法 ,sizeIsSticky=false word=long[1] (右移6位)+1为数组大小 | |
| BitSet(int nbits) | 构造方法 ,sizeIsSticky=true 就是说你需要这么多nbits到底需要多少个word进步保存呢 | |
| BitSet(long[] words) | 直接传入words数组,直接定义word,一个word可以表示64个bit | |
| static BitSet valueOf(longs) | 它会去掉空long值(也就对这个word根本就没有使用)构建BitSet | |
| byte[] toByteArray() | 转换成byte数组 | |
| long[] toLongArray() | 转换成long数组 | |
| void flip (int bitIndex) | 反转某个位的值,由1变成0,或由0变成1 | |
| void flip (int fromIndex, int toIndex) | 反转一段值[fromIndex,toIndex) | 1 |
| void set(int bitIndex) | 设置某个bit为1 | |
| void set(int fromIndex, int toIndex) | 设置一个范围内bit为1,跟flip类似,只是最后是或运算,不是异或运算 | |
| void clear(int bitIndex) | 对应bit位设置为0 | |
| BitSet get(int fromIndex, int toIndex) | 获取一段bit位的BitSet | |
| int nextSetBit(int fromIndex) | 获取下一个已经设置的bit位的位置 | |
| Long.numberOfTrailingZeros(word) | 取最后一个1位对应后面跟着0的个数,比如1111 1000,这就是3 | |
| int nextClearBit(int fromIndex) | 下一个空闲bit位置,也就是值为0 | |
| boolean intersects(BitSet set) | 两个BitSet是否存在交集 | |
| void and(BitSet bitset) | 进行and运算 | |
| void or(BitSet bitset) | 进行or运算 | |
| void xor(BitSet bitset) | 异或运算 |
2.1、void flip(int fromIndex, int toIndex)
3、总结
- 找到对应word
- 是否需要扩容
- 找到对应bit 位
- 做对应操作
4、应用场景思考
- 布尔过滤过滤器
- 应用两种状态字段的值,比如判断某个用户是否登录。

本文详细解读Java BitSet源码,涉及构造方法、成员变量、关键方法如flip和set,以及应用场景如布尔过滤和状态判断。通过剖析BitSet如何用long数组表示64位,实现位操作和内存管理。
278





