位图的简单介绍和实现

位图是什么?

介绍位图之前先来看看集合。我们平时开发中经常会用到各种各样的集合,集合支持往里面放数据,查看是否包含某个元素等。
比如说HashSet,是一个不可有重复元素的集合,此时如果用HashSet来存放数据,1,4,6三个数据,那int整数类型每个都是32位的4Byte大小,占用着12Byte大小。那如果这个数字是有范围的话,是否可以省略一些空间?

比如在范围在0~31,如果正常用集合来存,就是32个数, 占用32 * 4 = 128Byte,那如果用位图来存呢? 只需要4个Byte即可。

如何使用位图来实现?
只需要用一个int类型整数来存即可,因为每个int类型都是4字节大小,1字节 = 8 bit,4字节就是32bit,那如果用每一位来代表0~31范围之间内的数,不就可以用1个数就解决了0 ~ 31之间数的存储么?
举例:
0: 00000000 00000000 00000000 00000000 正常用二进制表示0,就是32个0,那如果每一位都代表着一个数,32位正好可以用来存储0 ~ 31。
如果用来存储1,那么只需要改变1位置的0 为 1即可,同理,如果将5加入里面,那么5位置的数字也变成1 即可。
那如果范围大于31呢? 比如 0 ~ 128
那么用一个Int[]即可,数组多长呢? 数组中每个元素都可以存储0 ~ 31个数,那用数组的0位置存储0 ~ 31,1位置存储 32 ~ 63依次类推,那么只需要4长度的int[]即可。

位图的功能

最常见的就是redis中的布隆过滤器(判断一个元素是否在集合中),ES底层的RBM压缩算法。
这其中都有着位图的思想在里面。

位图的好处

压缩空间!!!!

位图的实现

如何实现位图

创建一个BitMap类

首先,创建一个类,并且类用有一个long[]类型成员变量(int[]也可),并在构造器中赋值长度。
我这里是用了一个静态内部类。
为什么要 >> 6? 因为如果max是0或者<64的数,也是需要1长度的数组来存储。

 public static class BitMap {

        long[] bit;

        public BitMap(int max) {
            // (max + 64) >> 6 -> (max + 64) / 64
            bit = new long[(max + 64) >> 6];
        }
    }

添加元素

因为是long类型数组,所以每个元素可存储0 ~ 63个数
首先,要计算添加的元素要存储在数组下标为几的地方(bit[num >> 6] )。
其次,要计算元素在索引处的值的二进制位中的位置(num & 63 == num % 64)。

为什么 num & 63 == num % 64? num % 64的范围在 0 ~ 63之间
假设 num的二进制为 00000000 00000000 00000010 10010111
64的二进制为 00000000 00000000 00000000 01000000
那么 num % 64的结果,就是只剩下二进制的后7位0010111 ,
而&运算,都为1才为1,所以结果与% 64结果相同,但&运算速度很快。
上一步操作已经找到要存放的位置,再用| 操作,将1 左移 通过| 操作赋值

public void add(int num) {
      bit[num >> 6] |= (1L << (num & 63));
 }

删除元素

删除元素是将该位置置0,所以还是找到所在位置,取反后,该位置为0。

public void delete(int num) {
            bit[num >> 6] &= ~(1L << (num & 63));
        }

包含元素

public boolean contains(int num) {
           return (bit[num >> 6] & (1L << (num & 63))) != 0;
       }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值