位图概念、用法及实现
1 概念
位图(BitMap)可以用极少的空间保存很大的数值
通过一个bit数组来存储特定数据的一种数据结构,每一个bit位都能独立包含信息,bit是数据的最小存储单元,因此能大量节省空间
我们都知道在Java中int类型是占四个Byte,一个Byte有8bit
1 0 0 0 0 0 0 0 0 【8bit,一个字节,此时1在第8位,可以表示7这个数】
下面我们使用的是long类型,因此可以表示0~63(共64位数)
2 实现
BitMap:
public static class BitMap{
private long[] bits;
public BitMap(int max){
//(max + 64) >> 6 等同于 (max + 64) / 64
bits = new long[(max + 64) >> 6];
}
public void add(int num){
//num >> 6 等同于 num / 64 【可以确定我们要添加的整数】
// num % 64 等同于 num & 63
bits[num >> 6] |= (1L << (num & 63));//利用|运算,将对应位置置为1
}
public void delete(int num){
bits[num >> 6] &= ~(1L << (num & 63));
}
public boolean contains(int num){
return (bits[num >> 6] & (1L << (num & 63))) != 0;//与对应位置相与,判断结果是否为0
}
}
全代码及测试代码:
BitMapTest:
测试代码与hash表进行比较,观察所存数字
public class BitMapTest {
public static class BitMap{
private long[] bits;
public BitMap(int max){
//(max + 64) >> 6 等同于 (max + 64) / 64
bits = new long[(max + 64) >> 6];
}
public void add(int num){
//num >> 6 等同于 num / 64 【可以确定我们要添加的整数】
// num % 64 等同于 num & 63
bits[num >> 6] |= (1L << (num & 63));//利用|运算,将对应位置置为1
}
public void delete(int num){
bits[num >> 6] &= ~(1L << (num & 63));
}
public boolean contains(int num){
return (bits[num >> 6] & (1L << (num & 63))) != 0;//与对应位置相与,判断结果是否为0
}
}
public static void main(String[] args) {
System.out.println("测试开始-----");
int max = 10000;
BitMap bitMap = new BitMap(max);
HashSet<Integer> set = new HashSet<>();
int testTime = 1000000;
for (int i = 0; i < testTime; i++) {
int num = (int)(Math.random() * (max + 1));
double decide = Math.random();
if(decide < 0.333){
bitMap.add(num);
set.add(num);
} else if(decide < 0.666){
bitMap.delete(num);
set.remove(num);
} else {
if(bitMap.contains(num) != set.contains(num)){
System.out.println("Oops .....");
break;
}
}
}
for (int num = 0; num <= max; num++) {
if(bitMap.contains(num) != set.contains(num)){
System.out.println("Oops....");
}
}
System.out.println("测试结束----");
}
}