java使用bitmap实现可回收自增id的示例

 更新时间:2024年10月25日 11:35:09   作者:水中加点糖  
本文主要介绍了java使用bitmap实现可回收自增id的示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

需求描述

设计一个方法,每次调用返回一个自增id,同时需要满足以下要求。

  • 可更新id的状态为已使用,已使用的id下次调用时不再返回
  • 可修改某个id的状态为未使用,下次调用时设为未使用状态的id可重新被返回

思路

思路一:如果数据量非常小,直接使用一个集合存储已使用的id,使用循环和维护这个集合即可,但数据量大了,此方法返回数据的时间复杂度和占用的空间都是比较大的。

思路二(推荐):建立一个(位图)bitmap,初始时bitmap的每一位都为0,0代表未使用,1代表已使用。每次请求获取id时从此bitmap的第0位开始返回一个未使用的index即可。

以一个bitmap长度为65536的bitmap为例,示意图如下:

初始时每一个bit位值都为0

012345678……1024……65535
000000000……0……0

此时请求id返回的值为:0

012345678……1024……65535
111110111……1……0

如经过一段时间后,索引位置为5的数据变成了0未使用
此时请求id返回的值应为:5

具体实现

BitSet VS RoaringBitmap

解决思路有了,接下来就是代码实现。这里以java代码为例,可以直接使用jdk自带的java.util.BitSet实现,不过自带的BitSet在数据稀疏的场景下占用空间较大,且提供的原生方法较少。

这里推荐直接使用由2016年由几位大佬论文而开发的RoaringBitmap,可移步它的官网详细学习一把。https://roaringbitmap.org/about/

roaringBitmap

RoaringBitmap有java、go、c\c++、rust、swift等多个版本的实现,同时其时间与空间复杂度低,提供的方法也非常丰富。
github地址如下:https://github.com/RoaringBitmap

java代码实现

以下为《使用bitmap实现可回收自增id》的示例代码

引入依赖

		<dependency>
			<groupId>org.roaringbitmap</groupId>
			<artifactId>RoaringBitmap</artifactId>
			<version>1.0.0</version>
		</dependency>

示例代码:

    public static void main(String[] args) {
        RoaringBitmap rr = new RoaringBitmap();
        long l = rr.nextAbsentValue(0);
        System.out.println(l);//print 0
        rr.add(0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 1024, 1025);

        l = rr.nextAbsentValue(0);
        System.out.println(l);//print 5
        // index 5 set true(1)
        rr.add(5);
        l = rr.nextAbsentValue(0);
        System.out.println(l);//print 11
    }

输出结果:

0
5
11

以上代码使用new RoaringBitmap()定义了一个可以自动扩容的bitmap,add方法的入参代表将某个bit位设为1,nextAbsentValue方法返回从某个index位开始出现的第一个bit位为0的索引值

分布式自增可回收id实现方案

RoaringBitmap还有一大特点:支持序列化与反序列化。

roaringWithKryo

凭借这一特点,如需要在分布式场景下使用RoaringBitmap,则仅需稍微修改代码即可快速实现。

如将RoaringBitmap序列化为二进制存储在数据库中。

比如在mongodb中使用Binary data数据类型、mysql中使用blob数据类型、oracle中使用BLOB这些二进制类型存储RoaringBitmap即可。

实现时每次先将RoaringBitmap读取到程序中,再进行逻辑操作,修改后再写回数据库中。

总结一下

RoaringBitmap YYDS

到此这篇关于java使用bitmap实现可回收自增id的示例的文章就介绍到这了,更多相关java 可回收自增id内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • SpringCloud Gateway路由表配置实现小结

    SpringCloud Gateway路由表配置实现小结

    SpringCloudGateway通过路由表将请求转发到不同的服务或地址,每个路由包含id、uri、predicates和filters等字段,下面就来介绍一下SpringCloud Gateway路由如何配置,感兴趣的可以了解一下
    2026-01-01
  • Java数组的定义与使用

    Java数组的定义与使用

    数组是有序的元素序列,若将有限个类型相同的变量的集合命名,那么这个名称为数组名。本文通过代码示例详细介绍了Java数组的定义和使用,对学习或工作有一定的帮助,需要的小伙伴欢迎阅读
    2023-04-04
  • SpringBoot实现单点登录(SSO)的四种方案

    SpringBoot实现单点登录(SSO)的四种方案

    单点登录(Single Sign-On,SSO)是企业应用系统中常见的用户认证方案,它允许用户使用一组凭证访问多个相关但独立的系统,无需重复登录,本文给大家介绍了SpringBoot实现单点登录(SSO)的四种方案,需要的朋友可以参考下
    2025-04-04
  • Java实现ByteArray与String互转的常见转换方法

    Java实现ByteArray与String互转的常见转换方法

    在现代 Java 开发中,处理字节数据(byte[])和字符串(String)之间的转换是一项常见且至关重要的任务,无论是网络通信、文件操作、加密解密还是序列化反序列化,我们都需要在 byte[] 和 String 之间进行高效、准确的转换,所以本文介绍了ByteArray与String互转方法
    2025-12-12
  • Java9的一些新特性介绍

    Java9的一些新特性介绍

    这篇文章主要介绍了Java9的一些新特性介绍,Java随着其开源的特点和甲骨文的推动正在不断改进中,需要的朋友可以参考下
    2015-07-07
  • spring boot如何使用spring AOP实现拦截器

    spring boot如何使用spring AOP实现拦截器

    本篇文章主要介绍了spring boot如何使用spring AOP实现拦截器,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-04-04
  • 详解Maven打包和运行

    详解Maven打包和运行

    这篇文章主要介绍了Maven打包和运行的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-07-07
  • Java源码解析ConcurrentHashMap的初始化

    Java源码解析ConcurrentHashMap的初始化

    今天小编就为大家分享一篇关于Java源码解析ConcurrentHashMap的初始化,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • java运行shell脚本方法示例

    java运行shell脚本方法示例

    利用Runtime.execute方法,我们可以在Java程序中运行Linux的Shell脚本,或者执行其他程序
    2013-12-12
  • Spring Boot 简介(入门篇)

    Spring Boot 简介(入门篇)

    Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。下面通过本文给大家介绍spring boot相关知识,需要的的朋友参考下吧
    2017-04-04

最新评论