java:java.util.BitSet对象的Jackson序列化和反序列化实现
java.util.BitSet是个非常方便的比特位数据存储和操作类,一个 bit 具有2个值:0和1,正好可以用来表示 false 和 true,适用于判断“数据是否存在”的场景。
但是,这个从JDK1.0版本就存在的类,Jackson,Fastjson这些主流的JSON工具却并没有对它提供序列化和反序列化支持。
所以如果要在自己的数据结构中用到BitSet,就要自己实现序列化和反序列化。
上篇博客《java:java.util.BitSet对象的Fastjson序列化和反序列化实现》介绍了Fastjson实现,本文说明Jackson如何支持BitSet类型的序列化和反序列化
以下是BitSet对象的Jackson序列化和反序列化实现,
主要思路就是在序列化过程中将BitSet的数据转为JSON数组(如[7707,8822]或单个数字(当设置SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED特性时).
在反序列化阶段,根据TOKEN类型不同,将数据序列化为long[]再调用BitSet.valueOf方法转为BitSet对象返回。
/*** {@link BitSet} 的JACKSON序列化和反序列化实现* @author guyadong* @since 3.30.1*/
public class BitsetJacksonCodec {public static final Deserializer DESERIALIZER = new Deserializer();public static final Serializer SERIALIZER = new Serializer();/*** {@link BitSet}反序列化实现*/public static class Deserializer extends JsonDeserializer<BitSet> {private final JsonDeserializer<?> longArrayDeserializer = PrimitiveArrayDeserializers.forType(long.class);@Overridepublic BitSet deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {ObjectMapper mapper = (ObjectMapper) jp.getCodec();switch(jp.currentTokenId()) {case JsonTokenId.ID_NULL:jp.nextToken();return null;case JsonTokenId.ID_START_ARRAY:{long[] longs = (long[]) longArrayDeserializer.deserialize(jp, ctxt);return BitSet.valueOf(longs);}case JsonTokenId.ID_STRING:{/** 将文本递归解析 */String text = jp.getText();jp.nextToken();return mapper.readValue(text, BitSet.class);}default:{/** 数字类型:VALUE_NUMBER_INT */BitSet bitSet = BitSet.valueOf(new long[] {jp.getNumberValue().longValue()});jp.nextToken();return bitSet;}}}}/*** {@link BitSet}序列化实现*/public static class Serializer extends JsonSerializer<BitSet> {@SuppressWarnings({ "rawtypes" })private final JsonSerializer longArraySerializer = StdArraySerializers.findStandardImpl(long[].class);@SuppressWarnings("unchecked")@Overridepublic void serialize(BitSet value, JsonGenerator gen, SerializerProvider serializers)throws IOException, JsonProcessingException {if(null == value) {gen.writeNull();}else {longArraySerializer.serialize(value.toLongArray(), gen, serializers);}}}
}
测试及调用示例:
@Testpublic void test5JacksonCodec() {try {BitSet bitSet = BitSet.valueOf(new byte[] {27,30});ObjectMapper mapper = new ObjectMapper();SimpleModule module = new SimpleModule().addDeserializer(BitSet.class, BitsetJacksonCodec.DESERIALIZER).addSerializer(BitSet.class, BitsetJacksonCodec.SERIALIZER);mapper.registerModule(module);{/** 序列化为数组 */ String json = mapper.writeValueAsString(bitSet);log("JSON:{}",json);assertTrue(json.equals("[7707]"));BitSet parsed = mapper.readValue(json, BitSet.class);assertTrue(bitSet.equals(parsed));}{mapper.enable(SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED);/** 序列化为数字 */ String json = mapper.writeValueAsString(bitSet);log("JSON:{}",json);assertTrue(json.equals("7707"));BitSet parsed = mapper.readValue(json, BitSet.class);assertTrue(bitSet.equals(parsed));}{mapper.disable(SerializationFeature.WRITE_SINGLE_ELEM_ARRAYS_UNWRAPPED);/** 序列化为数字 */ String json = mapper.writeValueAsString(new TestBean(bitSet, 32));log("JSON:{}",json);assertTrue(json.equals("{\"bitSet\":[7707],\"age\":32}"));TestBean parsed = mapper.readValue(json, TestBean.class);assertTrue(bitSet.equals(parsed.bitSet));}}catch (Throwable e) {e.printStackTrace();fail();}}public static class TestBean{BitSet bitSet;Integer age;public TestBean() {}public TestBean(BitSet bitSet, Integer age) {this.bitSet = bitSet;this.age = age;}public BitSet getBitSet() {return bitSet;}public void setBitSet(BitSet bitSet) {this.bitSet = bitSet;}public Integer getAge() {return age;}public void setAge(Integer age) {this.age = age;}}
完整实现代码参见码云仓库:https://gitee.com/l0km/sql2java/blob/dev/sql2java-base/src/main/java/gu/sql2java/json/BitsetJacksonCodec.java
完整测试代码参见码云仓库:https://gitee.com/l0km/sql2java/blob/dev/sql2java-base/src/test/java/gu/sql2java/BitSetJsonCodecTest.java
相关文章:
java:java.util.BitSet对象的Jackson序列化和反序列化实现
java.util.BitSet是个非常方便的比特位数据存储和操作类,一个 bit 具有2个值:0和1,正好可以用来表示 false 和 true,适用于判断“数据是否存在”的场景。 但是,这个从JDK1.0版本就存在的类,Jackson,Fastjso…...
Go语言学习01-基本程序结构
文章目录 Go语言学习01-基本程序结构基本程序结构应用程序入口退出返回值编写测试程序快速设置连续值基本数据类型类型的预定义值指针类型运算符算数运算符比较运算符用 比较数组 逻辑运算符位运算符&^ 按位 置零 Go语言学习01-基本程序结构 基本程序结构 package main …...
rundeck k8s部署踩坑
1、镜像启动后原来的定时任务无法运行 参考: https://github.com/rundeck/rundeck/issues/4275 https://stackoverflow.com/questions/60942785/env-variable-for-rundeck-feature-joblifecycleplugin-enabled/60959605#60959605 结论: (1&…...
每天学习几道面试题|Kafka(二)架构设计类
文章目录 1. Kafka 是如何保证高可用性和容错性的?2. Kafka 的存储机制是怎样的?它是如何处理大量数据的?3. Kafka 如何处理消费者的消费速率低于生产者的生产速率?4. Kafka 集群中的 Controller 是什么?它的作用是什么…...
Spring 实现 OAuth2 授权之解决方案
Spring Security OAuth2 - 已经废弃的项目 早期的Spring 使用 Spring Security OAuth2 实现 OAuth 2.0 的认证服务器和资源服务器。OAuth2是一个授权框架,它允许第三方应用获取有限的访问权限,而无需获取用户的账号和密码等敏感信息。通过这种方式,OAuth2协议实现了安全的用…...
el-select使用filterable下拉无法关闭得问题
这里推荐一个前端框架 sakuya / SCUI,他里面有个formTable,可以解决很多订单明细保存得问题。基本沿用element-plus的前端使用模式,让表单表格变的非常容易。 这个的供应商插件,当使用filterable后,点击表格重的选项&…...
基于javaweb(springboot)城市地名地址信息管理系统设计和实现
基于javaweb(springboot)城市地名地址信息管理系统设计和实现 博主介绍:多年java开发经验,专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《1000套》 欢迎点赞 收藏 ⭐留言…...
vue iframe实现父页面实时调用子页面方法和内容
父页面标签添加鼠标按下事件 父页方法中建立iframe通信 实时调用子页面方法 实时更改子页面文本内容...
HarmonyOS ArkTS 开发基础/语言
目录 一、ArkUI (方舟开发框架) 概述 1.1 基本概念 1.2 两种开发范式 1.3 不同应用类型支持的开发范式 二、ArkTS 声明式开发范式 2.1 开发能力 2.2 整体架构 三、ArkTS 基础类型 3.1 Any 类型 3.2 数字类型 3.3 字符串类型 3.4 布尔类型 3.5 联合类型 3.6 数组类…...
AI大模型学习
AI大模型学习 在当前技术环境下,AI大模型学习不仅要求研究者具备深厚的数学基础和编程能力,还需要对特定领域的业务场景有深入的了解。通过不断优化模型结构和算法,AI大模型学习能够不断提升模型的准确性和效率,为人类生活和工作…...
2024年【T电梯修理】考试内容及T电梯修理作业考试题库
题库来源:安全生产模拟考试一点通公众号小程序 T电梯修理考试内容根据新T电梯修理考试大纲要求,安全生产模拟考试一点通将T电梯修理模拟考试试题进行汇编,组成一套T电梯修理全真模拟考试试题,学员可通过T电梯修理作业考试题库全真…...
2.vscode 配置python开发环境
vscode用着习惯了,也不想再装别的ide 1.安装vscode 这一步默认已完成 2.安装插件 搜索插件安装 3.选择调试器 Ctrl Shift P(或F1),在打开的输入框中输入 Python: Select Interpreter 搜索,选择 Python 解析器 选择自己安…...
[蓝桥杯 2015 省 B] 生命之树
题目链接 [蓝桥杯 2015 省 B] 生命之树 题目描述 在 X 森林里,上帝创建了生命之树。 他给每棵树的每个节点(叶子也称为一个节点)上,都标了一个整数,代表这个点的和谐值。 上帝要在这棵树内选出一个节点集合 S S S&…...
为什么Hashtable不允许插入nuIl键和null值?
1、典型回答 浅层次的来回答这个问题的答案是,JDK 源码不支持 Hashtable 插入 value 值为 null,如以下 JDK 源码所示: 也就是 JDK 源码规定了,如果你给 Hashtable 插入 value 值为 null 就会抛出空指针异常。 并且看上面的 JDK …...
【WPF应用4】WPF界面对象编辑
简介 WPF(Windows Presentation Foundation)是.NET框架的一部分,它为开发人员提供了一个用于构建桌面应用程序用户界面的强大平台。WPF界面对象编辑是指在WPF应用程序中创建、设计和修改用户界面元素的过程。这些界面对象不仅包括基本的控件…...
js数组去重常见方法
简单数组 1、使用filter()方法:通过filter()方法遍历数组,返回仅包含首次出现的元素的新数组。 const arr [1, 2, 3, 4, 2, 3, 5]; const list arr.filter((item, index) > arr.indexOf(item) index); console.log(list); // [1, 2, 3, 4, 5]2、…...
【Java Web基础】一些网页设计基础(二)
文章目录 1. Bootstrap导航栏设计1.1 代码copy与删减效果1.2 居中属性与底色设置1.3 占不满问题分析1.4 字体颜色、字体大小、字体间距设置1.5 修改超链接hover颜色,网站首页字体颜色 1. Bootstrap导航栏设计 1.1 代码copy与删减效果 今天设计导航栏,直…...
python中tkinter计算器
本文使用创作助手。 以下是一个用Python的Tkinter库编写的简单计算器的示例代码: import tkinter as tkdef btn_click(btn_val):current_text entry.get()new_text current_text btn_valentry.delete(0, tk.END)entry.insert(tk.END, new_text)def calculate()…...
[嵌入式系统-39]:龙芯1B 开发学习套件 -9-PMON的文件结构
目录 前言: 一、PMON-V1.1 目录结构 二、Targets目录的组成 前言: 参考:龙芯相关 - 心映真的空间 一、PMON-V1.1 目录结构 PMON-V1.1 目录结构 pmon的目录结构大致如下(由linux工具tree生成) |-- Tar…...
[蓝桥杯2012] 罗马数字
罗马数字 题目描述 古罗马帝国开创了辉煌的人类文明,但他们的数字表示法的确有些繁琐,尤其在表示大数的时候,现在看起来简直不能忍受,所以在现代很少使用了。之所以这样,不是因为发明表示法的人的智力的问题…...
不止于抓包:解锁Charles与Burp Suite联动的高级玩法,打造你的移动安全测试工作流
移动安全测试进阶:Charles与Burp Suite高效联动实战指南 当你已经能够熟练使用Charles或Burp Suite单独进行抓包分析时,是否想过将两者的优势结合起来,打造一个更强大的移动安全测试工作流?本文将带你超越基础抓包操作,…...
从MOT17到VTMOT:手把手教你用PFTrack评估双模态跟踪模型(附结果解读)
从MOT17到VTMOT:深度解析双模态跟踪模型的评估艺术 当你在VTMOT数据集上运行完PFTrack模型,看着终端输出的三张评估表格(HOTA、CLEAR、Identity)时,是否曾困惑于这些数字背后的真实含义?本文将带你穿透指标…...
微信小程序ECharts图表Canvas层级覆盖问题:从原理到实战解决方案
1. 微信小程序ECharts图表Canvas层级问题解析 第一次在小程序里用ECharts做数据可视化时,我就被这个坑绊倒了——明明设置了z-index,为什么滚动页面时图表还是会盖住弹窗和导航栏?后来才发现,这是微信小程序原生组件的"特权&…...
D3KeyHelper:暗黑破坏神3自动化战斗系统架构解析与实践指南
D3KeyHelper:暗黑破坏神3自动化战斗系统架构解析与实践指南 【免费下载链接】D3keyHelper D3KeyHelper是一个有图形界面,可自定义配置的暗黑3鼠标宏工具。 项目地址: https://gitcode.com/gh_mirrors/d3/D3keyHelper D3KeyHelper是一款基于AutoHo…...
如何快速解密微信聊天记录:WechatDecrypt工具完全指南
如何快速解密微信聊天记录:WechatDecrypt工具完全指南 【免费下载链接】WechatDecrypt 微信消息解密工具 项目地址: https://gitcode.com/gh_mirrors/we/WechatDecrypt 微信聊天记录承载着我们珍贵的回忆和重要的工作沟通,但当更换设备或需要数据…...
不上APM,103行代码搞定慢SQL检测:超100毫秒自动入库
不上APM,103行代码搞定慢SQL检测:超100毫秒自动入库 原创于 2026-04-14 06:40:21 发布更新于 2026-04-14 10:30:00 非科班野生程序员,深耕政务信息化20年。从VC到PB再到Java,自研框架browise也打磨了十几年。最近整理框架代码&…...
哔哩下载姬:B站视频下载工具的专业解决方案与技术应用指南
哔哩下载姬:B站视频下载工具的专业解决方案与技术应用指南 【免费下载链接】downkyi 哔哩下载姬downkyi,哔哩哔哩网站视频下载工具,支持批量下载,支持8K、HDR、杜比视界,提供工具箱(音视频提取、去水印等&a…...
Windows安卓子系统(WSA)实用指南:3步快速部署与5大优化技巧
Windows安卓子系统(WSA)实用指南:3步快速部署与5大优化技巧 【免费下载链接】WSA Developer-related issues and feature requests for Windows Subsystem for Android 项目地址: https://gitcode.com/gh_mirrors/ws/WSA 你是否想在Windows 11电脑上无缝运行…...
如何快速提升AutoTrain Advanced文本摘要的ROUGE分数:5个实用优化技巧
如何快速提升AutoTrain Advanced文本摘要的ROUGE分数:5个实用优化技巧 【免费下载链接】autotrain-advanced 🤗 AutoTrain Advanced 项目地址: https://gitcode.com/gh_mirrors/au/autotrain-advanced AutoTrain Advanced是一款强大的文本摘要工具…...
快速构建GraphQL服务器:Mercurius入门完整指南
快速构建GraphQL服务器:Mercurius入门完整指南 【免费下载链接】mercurius Implement GraphQL servers and gateways with Fastify 项目地址: https://gitcode.com/gh_mirrors/me/mercurius Mercurius是一个专为Fastify设计的GraphQL适配器,它让开…...
