散列表- 位图
1.1 位图的介绍
-
Bitmap 的基本原理就是用一个 bit 来标记某个元素对应的 Value,而 Key 即是该元素。由于采用一个bit 来存储一个数据,因此可以大大的节省空间
-
Java 中 int 类型占用 4 个字节,即 4 byte,又 1 byte = 8 bit,所以 一个 int 数字的表示大概如下
位图的实现 -
1 . 初始化数组大小
- 假设N就是位图中的最大值,那么数组的长度就应该是N / 32 + 1,等同于 (N + 1) >> 5
-
2 . 加入元素
- N >> 5 找到索引值
- N % 32 余数就是索引值所在32位的具体位置,等同于N & 31
- 让1 左移N &31位和数组索引位置值得二进制做个 | 运算
-
3 . 删除元素
- 删除元素和增加元素类似,在处理结果时让索引位置的值 & ~(1 << (N & 31))
就把这个位置上设置成0了
- 删除元素和增加元素类似,在处理结果时让索引位置的值 & ~(1 << (N & 31))
-
4 . 判断元素是否存在
- 这个是和add差不多的操作,查看N的索引N的位置的这个值是否为1
直接 (arr[val >> 5] & (1 << (val & 63))) != 0 即可
- 这个是和add差不多的操作,查看N的索引N的位置的这个值是否为1
1.2 手动实现位图
package com.lagou.bitMap.entity;
/**
* @author 云梦归遥
* @date 2022/5/13 18:10
* @description
*/
public class BitMap {
private int[] map; // 存储数据的数组
private int length = 1; // 数组的默认长度
public BitMap(){
this.map = new int[length];
}
// 扩容数组
public void resize(){
int[] newMap = new int[length];
System.arraycopy(map, 0, newMap, 0, map.length);
map = newMap;
System.out.println("【位图扩容成功】");
}
// 增加元素
public void add(int num){
if (num > length * 32 - 1){
// 进行扩容
length = (num >> 5) + 1;
resize();
}
map[num >> 5] |= 1 << ((num - (num >> 5) * 32) & 31);
}
// 删除元素
public void delete(int num){
map[num >> 5] &= ~(1 << ((num - (num >> 5) * 32) & 31));
}
// 查询
public boolean select(int num){
return (map[num >> 5] & (1 << ((num - (num >> 5) * 32) & 31))) != 0;
}
}
进行测试
package com.lagou.bitMap.test;
import com.lagou.bitMap.entity.BitMap;
/**
* @author 云梦归遥
* @date 2022/5/13 18:26
* @description
*/
public class BitMapTest {
public static void main(String[] args) {
BitMap bitMap = new BitMap();
bitMap.add(1);
bitMap.add(10);
bitMap.add(30);
bitMap.add(70);
bitMap.add(90);
System.out.println(bitMap.select(5)? "5 元素存在": "5 元素不存在");
System.out.println(bitMap.select(10)? "10 元素存在": "10 元素不存在");
System.out.println(bitMap.select(50)? "50 元素存在": "50 元素不存在");
System.out.println(bitMap.select(90)? "90 元素存在": "90 元素不存在");
bitMap.delete(10);
System.out.println(bitMap.select(10)? "10 元素存在": "10 元素不存在");
}
}
1.3 总结
JAVA中一个int占4字节,32位二进制数, 如果一个int整数32位二进制都表示一个数的话,那么一个整数能表示[0,31]。如果想表示[32,64]可以加入数组,让索引0位置的数表示[0,31],索引1表示[32,64],以此类推只要知道要存入的最大值,就可以实现一个比原来数组占用空间至少小32倍的数组 ,就是位图