BitSet原理简介

1.定义

    Bitset是Java中的一种数据结构。Bitset中主要存储的是二进制位,做的也都是位运算,每一位只用来存储0,1值,主要用于对数据的标记。可用于判断数据是否重复。

2.实例

 public static void main(String[] args) {
        String str="test";
        String str2="test";
        BitSet bitSet=new BitSet();
        //str.hashCode()&0x7FFFFFFF保证了传入的一定是一个正数
        bitSet.set(str.hashCode()&0x7FFFFFFF);
        bitSet.set(str.hashCode()&0x7FFFFFFF);
        System.out.println(bitSet.get(str.hashCode()&0x7FFFFFFF));
}

3.源码说明

    可以看到,BitSet的底层实现是使用long数组作为内部存储结构的,这就决定了BitSet至少为一个long的大小,而且BitSet的大小为long类型大小(64位)的整数倍。 

    long数组的每一个元素都可以当做是64位的二进制数,也是整个BitSet的子集。在BitSet中把这些子集叫做[Word]。

  3.1构造参数

     下面主要介绍了无参的构造函数,有参的只是初始化了长度不为0 的BitSet,其他不变.

/**
*  1>>6=64刚好对应long的64位,应为采用的是long的数组,
*  一个数据存储的最多为6字节
*/
private final static int ADDRESS_BITS_PER_WORD = 6;
public BitSet() {
        //初始化大小 words数据集合的大小,默认是0
        initWords(BITS_PER_WORD);
        sizeIsSticky = false;
}
//初始化words的大小
private void initWords(int nbits) {
     words = new long[wordIndex(nbits-1) + 1];
}
获取words数组的长度
private static int wordIndex(int bitIndex) {
    //index=bitIndex /64  64刚好对应long的64位最多存储64个bit位  也就是最多能标识64个数据
    return bitIndex >> ADDRESS_BITS_PER_WORD;
}

    3.2.Set方法说明

     

public void set(int bitIndex) {
        if (bitIndex < 0)
            throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);

        int wordIndex = wordIndex(bitIndex);
        expandTo(wordIndex);
        //与该位置的原有结果进行一个或操作,保证如果同样位置的数据进行位运算后是存在的(即返回1)
        words[wordIndex] |= (1L << bitIndex); // Restores invariants

        checkInvariants();
}
//扩大内存
private void expandTo(int wordIndex) {
        int wordsRequired = wordIndex+1;
        //如果现在用你的words的大小小于需要的数组集合的大小就进行扩容
        if (wordsInUse < wordsRequired) {
            ensureCapacity(wordsRequired);
            wordsInUse = wordsRequired;
        }
}
//扩容
private void ensureCapacity(int wordsRequired) {
        if (words.length < wordsRequired) {
            // Allocate larger of doubled size or required size
            int request = Math.max(2 * words.length, wordsRequired);
            words = Arrays.copyOf(words, request);
            sizeIsSticky = false;
        }
}

3.3.Get方法说明

public boolean get(int bitIndex) {
        if (bitIndex < 0)
            throw new IndexOutOfBoundsException("bitIndex < 0: " + bitIndex);

        checkInvariants();

        int wordIndex = wordIndex(bitIndex);
        //当数据存在时  (words[wordIndex] & (1L << bitIndex))  结果将会返回我们在set是放入words中的数据
        return (wordIndex < wordsInUse)
            && ((words[wordIndex] & (1L << bitIndex)) != 0);
}

4.使用

BitSet的使用非常简单,只要对需要的操作调用对应的函数即可。

BitSet常见的应用场景是对海量数据的处理,可以用于对大数量的查找,去重,排序等工作,相比使用其他的方法,占用更少的空间,显著提高效率;也可以使用BitSet进行一些统计工作,比如日志分析、用户数统计等;还可以使用其方法做一些集合方面的运算,比如求并集、交集和补集等。有关BitSet的更多使用和应用,可以参考:BitSet的应用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值