Java中BitMap(位图)hutool版、IntMap、LongMap示例详解

 更新时间:2024年12月27日 10:26:34   作者:qq_41369135  
这篇文章主要给大家介绍了关于Java中BitMap(位图)hutool版、IntMap、LongMap的相关资料,通过位运算高效存储和检索整数,相比于传统数组,它们在内存占用和性能上都有显著优势,需要的朋友可以参考下

一、引入依赖

<dependency>
    <groupId>cn.hutool</groupId>
    <artifactId>hutool-all</artifactId>
    <version>5.5.1</version>
</dependency>

二、源码

BitMap (interface )

package cn.hutool.bloomfilter.bitMap;

public interface BitMap {
    int MACHINE32 = 32;
    int MACHINE64 = 64;

    void add(long var1);

    boolean contains(long var1);

    void remove(long var1);
}

IntMap (class)

package cn.hutool.bloomfilter.bitMap;

import java.io.Serializable;

public class IntMap implements BitMap, Serializable {
    private static final long serialVersionUID = 1L;
    private final int[] ints;

    public IntMap() {
        this.ints = new int[93750000];
    }

    public IntMap(int size) {
        this.ints = new int[size];
    }

    public void add(long i) {
        int r = (int)(i / 32L);
        int c = (int)(i % 32L);
        this.ints[r] |= 1 << c;
    }

    public boolean contains(long i) {
        int r = (int)(i / 32L);
        int c = (int)(i % 32L);
        return (this.ints[r] >>> c & 1) == 1;
    }

    public void remove(long i) {
        int r = (int)(i / 32L);
        int c = (int)(i % 32L);
        int[] var10000 = this.ints;
        var10000[r] &= ~(1 << c);
    }
}

LongMap(class) 

package cn.hutool.bloomfilter.bitMap;

import java.io.Serializable;

public class LongMap implements BitMap, Serializable {
    private static final long serialVersionUID = 1L;
    private final long[] longs;

    public LongMap() {
        this.longs = new long[93750000];
    }

    public LongMap(int size) {
        this.longs = new long[size];
    }

    public void add(long i) {
        int r = (int)(i / 64L);
        long c = i % 64L;
        this.longs[r] |= 1L << (int)c;
    }

    public boolean contains(long i) {
        int r = (int)(i / 64L);
        long c = i % 64L;
        return (this.longs[r] >>> (int)c & 1L) == 1L;
    }

    public void remove(long i) {
        int r = (int)(i / 64L);
        long c = i % 64L;
        long[] var10000 = this.longs;
        var10000[r] &= ~(1L << (int)c);
    }
}

三、以下纯属自学(自己测试,有问题请帮忙指出)

四、BigMap原理

原来如果我们要存储1,2,3,4四个整数,就需要new一个 长度为4的数组存储,如new int[3],占内存就是4x4=16byte。而现在入宫hutool的 IntMap,只需要 new IntMap[1]就够了,占内存1x4=4byte。

而且new IntMap[1]可以存储0-31这32个整数。用传统方法得new int[31],占内存就是32x4=128byte。他们两个的内存占比就是32:1(原始:IntMap)

1.IntMap是怎么存储的?add(long i)方法

1.1 我们先new IntMap[1]。int=4byte=32bit。所以得到如下32位二进制 。

00000000 00000000 00000000 00000000

我们都知道二进制只有0和1,在这里可以这么理解,如下面这样,代表存入这个0、7、31三个整数。简而言之,当我们只new 了1字节(32bit)大小的空间, 只要我们存入0-31内的某个数字,二进制对应位就会被置为1

10000000 00000000 00000000 10000001

如:

1.2 查看add方法解析

可以发现他做了以下操作。比如我们要存储 7 这个数字

r 代表7存放在index为0 tmp[0] 里

c 代表 7 该存放在tmp[0] 中32bit位哪个位置

着重 讲 this.ints[r] |= 1 << c (有三步操作),源码是  1左移7位后,第8个bit位从0变为1,如下:

初始 1 的二进制:

00000000 00000000 00000000 00000001

1.  1 左移7位后:

00000000 00000000 00000000 10000000

2.  最后与 ints[0] 进行或运算后得到,如下:

00000000 00000000 00000000 10000000

00000000 00000000 00000000 00000000  ints[0]

结果 :

00000000 00000000 00000000 10000000

3.  第三步,给 ints[0] 赋值 (把或运算的值付给ints[0])

注意:为什么要进行或运算  ,是因为要保留前面add得值。如此时我们已经add了 7 ,此时ints[0]为:

ints[0] = 00000000 00000000 00000000 10000000

我们再往里面 add一个 9 。程序又执行到或运算 那一步

00000000 00000000 00000010 00000000   新的 add  9  的值

00000000 00000000 00000000 10000000  ints[0]  原来add 7 的值

或运算后,7跟9的值都保存起了。如下:

ints[0] = 00000000 00000000 00000010 10000000

个人理解:

接上面第一步 左移7位 说,为什么要从1左移 c 位,我的理解:它的设计思想默认第一个bit位都放余数为0的数,如tmp[0]中的整数0,tmp[1]中的整数 32。其余数 位置都要+1bit位。从代码编写来说就变成 1<<c

2.contains(long i)方法与remove(long i)方法自己可以 根据以上去验证理解

五、同理,LongMap也是类似的思想

到此这篇关于Java中BitMap(位图)hutool版、IntMap、LongMap的文章就介绍到这了,更多相关Java BitMap、IntMap、LongMap内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:

相关文章

  • 详解SpringBoot如何统一后端返回格式

    详解SpringBoot如何统一后端返回格式

    今天我们来聊一聊在基于SpringBoot前后端分离开发模式下,如何友好的返回统一的标准格式以及如何优雅的处理全局异常,感兴趣的可以了解一下
    2021-07-07
  • Java中Set集合转为List集合常见的两种方式

    Java中Set集合转为List集合常见的两种方式

    List是Java中比较常用的集合类,指一系列存储数据的接口和类,可以解决复杂的数据存储问题,这篇文章主要给大家介绍了关于Java中Set集合转为List集合常见的两种方式,需要的朋友可以参考下
    2023-12-12
  • 详解IDEA社区版(Community)和付费版(UItimate)的区别

    详解IDEA社区版(Community)和付费版(UItimate)的区别

    这篇文章主要介绍了详解IDEA社区版(Community)和付费版(UItimate)的区别,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-11-11
  • java中的GC收集器详情

    java中的GC收集器详情

    这篇文章主要介绍了java中的GC收集器,GC(Garbage collection )指的是程序内存管理分手动和自动,手动内存管理,需要我们编程的时候显式分配和释放空间,但如果忘记释放,会造成严重的内存泄漏问题,下面文章内容我们就来实例说明情况,需要的朋友可以参考一下
    2021-10-10
  • Java模拟实现HashMap算法流程详解

    Java模拟实现HashMap算法流程详解

    在java开发中,HashMap是最常用、最常见的集合容器类之一,文中通过示例代码介绍HashMap为啥要二次Hash,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2023-02-02
  • java实现员工工资管理系统

    java实现员工工资管理系统

    这篇文章主要为大家详细介绍了java实现员工工资管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • Java之JsonArray用法讲解

    Java之JsonArray用法讲解

    这篇文章主要介绍了Java之JsonArray用法讲解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08
  • Tomcat启动分析(我们为什么要配置CATALINA_HOME环境变量)

    Tomcat启动分析(我们为什么要配置CATALINA_HOME环境变量)

    本文主要介绍Tomcat启动分析的知识,这里整理了相关资料及分析原因和如何实现的方法,有兴趣的小伙伴可以参考下
    2016-09-09
  • 解决JAVA项目启动卡住,无任何异常信息的问题

    解决JAVA项目启动卡住,无任何异常信息的问题

    这篇文章主要介绍了解决JAVA项目启动卡住,无任何异常信息的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-03-03
  • java中Javers 比较两个类的差异

    java中Javers 比较两个类的差异

    本文主要介绍了Javers 比较两个类的差异,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02

最新评论