写在前面
进入正题
首先从名字上大致就知道这个类是干嘛的,存储 Bit 的 Set,Bit 就是二进制数据01(理解成标志位就行,0没有,1有),而Set就是数学中的那个Set(集合),自己查资料。
拓展点:BitMap,有兴趣自己查资料。
先说下我是怎么理解 BitSet 设计理念的:
先开辟一块连续的内存(long 数组),因为long占64个bit,所以数组的每个格子就是64个bit。
找到对应的数组的格子,即找到数组的下标。要设置0到63号标志位的,定位到数组的下标是0,64到127定位到数组的小标是1,依此类推,简单说找下标就是位置x/64。
计算出并拿到指定编号位置设置标志位的值。上面说的数组的下标找到了,但是怎么设置一个bit位呢,long不是占64个bit吗?这里开始就有点意思了,比如说我要设置55号的标志位为1,那么我只要在long的64位中的第55号位设置为1就行了,这时需要用到移位操作,理论上有两种移动方式(1L<<55和Long.MIN_VALUE>>55),BitSet的设计者使用的是1向左移。
首次设置bit标志位。将上一步拿到的指定编号位置设置标志位的值直接赋值到数组的指定位置的下标就行了。
同个数组下标位置非首次设置bit标志位。上面说的只是数组的某个格子第一次设置值,如果有第二次设置的话还是这么操作的话就会被覆盖了,这时就需要按位或操作了,比如说第1次设置55号的标志为1,计算出并拿到指定编号位置设置标志位的值是(1L<<55),然后根据首次设置bit标志位的操作,将其赋值给数组的0下标;然后第2此设置20号的标志为1,计算出并拿到指定编号位置设置标志位的值是(1L<<20) ,这时就不能直接给赋值给数组的0下标了,而是要进行按位或((1L<<20) | (1L<<55))第20、55号都为1了,然后赋值给数组的0下标。
查询指定指定bit位是否为1。比如说20号,首先先找到数组的下标(看前面说,找到的下标为0),计算出并拿到指定编号位置设置标志位的值(还是看前面说,值为(1L<<20)),然后取出数组下标对应的值(比如说 arr[0]=0),然后进行按位与(0 & (1L<<20)),最后得到的结果为0,所以为false。
最后再来说下我觉得最有意思的 toString 方法,其它方法读者自行研究。迟点补上。。。。。。