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的应用