正常情况下,我们肯定是使用HashMap来判断
但是我们来计算下,10亿条数据所占用的内存
int 占用4个字节
4*1000000000/1024/1024/1024=3.725G内存
超过了1个G的内存,所以不能使用HashMap
我们可以使用位图BitMap,也就是二进制字节数组
一个字节占8个bit,我们吧编码当做索引,不占用内存,数组中的值占用内存。
前提是我们的编码都是正整数才能使用位图
我们来计算下所占用的内存
1000000000/8/1024/1024/1024=0.116G
小于1个G,所以我们使用位图,如果索引存在设置为1,不存在不管他
这样在查询的时候直接查询索引位置是不是1,就能拿到结果
这样时间复杂度就是O(1)的,在1秒内就能查询到
下面看代码
package com.example.demo.entity;
/**
* 二进制字节数组 就是位图BitMap
* 1个字节byte占8个位=8bit 0 0 0 0 0 0 0 0
*/
public class BitMap {
private int size;
private byte[]data;
public BitMap(int size){
this.size=size;
//10/8=1,不够2个字节,那么需要去借7个
//所以10+7=17/8=2,所以10个长度,放2个字节数组
this.data=new byte[(size+7)/8];
}
/**
* 存储二进制字节数组对应的索引 设置为1
* num当做索引位置
* 时间复杂度o(1)
*/
public void set(int num){
if(num>=size){
//索引越界
return;
}
//找到要存放到那个字节数组中
//10/8=1 数组从0开始,所以0表示第一个数组,1表示第二个数组
//也就是10要放到第二个字节数组中
int byteIndex=num/8;
//获取原字节数组中的数据
byte b=data[byteIndex];
//7 6 5 4 3 2 1 0 这里是索引的位置
//0 0 0 0 0 0 0 0 这里是第一个字节数组存放的0还是1
//15 14 13 12 11 10 9 8 这里是索引的位置
//0 0 0 0 0 0 0 0 这里是第二个字节数组存放的0还是1
//获取新的元素要左移的位置
//num%8表示10%8=2 表示右边距离的位置
//7是下标最后一位,左边减去右边,就是15那个位置要往右移动到10的位置
//左边是高位 右边是低位
int zy=7-(num%8);
//从左往右走 和之前的数据取或 有1就是1,说明之前存在1,不改变原来的数据,
//如果是新的数据1,那么放入1,这样新的数据有1,旧的数据也有1,这样在重新赋值给字节数组
//这样就添加成功了
data[byteIndex]=(byte)(b|1<<zy);
}
/**
* 从字节数组中获取是否存在
* num当做索引位置
* 时间复杂度o(1)
*/
public boolean get(int num){
if(num>=size){
//索引越界
return false;
}
//找到要存放到那个字节数组中
//10/8=1 数组从0开始,所以0表示第一个数组,1表示第二个数组
//也就是10要放到第二个字节数组中
int byteIndex=num/8;
//获取原字节数组中的数据
byte b=data[byteIndex];
//7 6 5 4 3 2 1 0 这里是索引的位置
//0 0 0 0 0 0 0 0 这里是第一个字节数组存放的0还是1
//15 14 13 12 11 10 9 8 这里是索引的位置
//0 0 0 0 0 0 0 0 这里是第二个字节数组存放的0还是1
//获取新的元素要左移的位置
//num%8表示10%8=2 表示右边距离的位置
//7是下标最后一位,左边减去右边,就是15那个位置要往右移动到10的位置
int zy=7-(num%8);
//从左往右走 和之前的数据取余
//如果都是1,那么才是1,如果有1个0,都是0,那么数组中不存在
return (b&1<<zy)!=0;
}
}
package com.example.demo.mapper;
import com.example.demo.entity.BitMap;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
public class Test {
public static void main(String[] args) {
BitMap bitMap=new BitMap(999999999);
bitMap.set(666);
bitMap.set(777);
bitMap.set(888);
System.out.println(bitMap.get(222));
System.out.println(bitMap.get(333));
System.out.println(bitMap.get(666));
System.out.println(bitMap.get(777));
System.out.println(bitMap.get(888));
}
}