数据结构-BitSet的实现原理-java.util.BitSet

今天看es看到,es使用bitset来标记一个文档是否匹配,于是就看了下java.util中的BitSet实现原理,记录一下

该数据结构能够实现什么

void set(int id):设置id存在
boolean get(int id): 查看id是否存在
容易想到用bit位的1或者0来代表, 那么一个long的长度8字节(64位),能存储64个位置的状态,对于id来说需要多少个long才能存储所有的状态位呢?答案是 id / 64
使用一个长度为id/64的long数组就可以存储所有的状态位

实现思路

初始化存储数组: long[] words

  • set(id)
  1. 计算数组下标(第几个long来存储该值的状态):id/64 = id >> 6;
  2. 计算该long的哪一位设置位1:将从右数第(id%64)的bit位设置为1: words[下标] |= 1 << id%64,等价于 words[id >> 6] |= 1L << id
    至于为啥等价,可能比较难理解,因为计算机在计算位移操作时,遵循以下规则:
    整形: int << num,由于int只有32位,左移数不能超过该值,int << num 等价于 int << num的后5位
    长整形: long << num,同理long << num 等价于 long << num的后6位
  3. 再来看下java.util.BitSet.set的实现
public void set(int bitIndex) {
        if (bitIndex < 0)
            throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);

        int wordIndex = wordIndex(bitIndex);
        expandTo(wordIndex);

        //重点看这里
        words[wordIndex] |= (1L << bitIndex); // Restores invariants

        checkInvariants();
    }
  • boolean get(id)
    set是将某一个bit位设置为1,get是判断某一个bit位是否为1
  1. 获取words数组下标,id >> 6
  2. 判断对应bit位是否为1, (1L << i) & words[id>>6] != 0
public boolean get(int bitIndex) {
        if (bitIndex < 0)
            throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);

        checkInvariants();

        int wordIndex = wordIndex(bitIndex);
        return (wordIndex < wordsInUse)
            && ((words[wordIndex] & (1L << bitIndex)) != 0);//重点看这里
    }

我们这里也发现只有在数量很多的时候,bitset才能体现出威力,不当使用效率并不高。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值