java:java.util.BitSet对象的Fastjson序列化和反序列化实现

java.util.BitSet是个非常方便的比特位数据存储和操作类,一个 bit 具有2个值:0和1,正好可以用来表示 false 和 true,适用于判断“数据是否存在”的场景。
但是,这个从JDK1.0版本就存在的类,Jackson,Fastjson这些主流的JSON工具却并没有对它提供序列化和反序列化支持。
所以如果要在自己的数据结构中用到BitSet,就要自己实现序列化和反序列化。
以下是BitSet对象的Fastjson序列化和反序列化实现,
主要思路就是在序列化过程中将BitSet的数据转为JSON数组(如[7707,8822])或十六进制字符串(如x'1B1E')或直接调用BitSet.toString()输出非标准JSON(如{0, 1, 3, 4, 9, 10, 11, 12}).
在反序列化阶段,根据TOKEN类型不同,将数据序列化为long[]byte[]int[]再调用BitSet.valueOf方法转为BitSet对象返回。

/*** {@link BitSet} 的FASTJSON序列化和反序列化实现* @author guyadong*/
public class BitSetFastjsonCodec implements ObjectSerializer, ObjectDeserializer{public static final BitSetFastjsonCodec INSTANCE = new BitSetFastjsonCodec();private BitSetSerializeType bitSetSerializeType = BitSetSerializeType.ARRAY;private final ObjectArrayCodec longArrayCodec = new ObjectArrayCodec();public BitSetFastjsonCodec() {}public BitSetFastjsonCodec(BitSetSerializeType bitSetSerializeType) {this.bitSetSerializeType(bitSetSerializeType);}/** 反序列化实现 */@SuppressWarnings({ "unchecked" })@Overridepublic <T>T deserialze(DefaultJSONParser parser, Type type, Object fieldName) {JSONLexer lexer = parser.lexer;switch(lexer.token()) {case JSONToken.NULL:lexer.nextToken(JSONToken.COMMA);return null;case JSONToken.LITERAL_STRING:{/** 递归 */String stringLiteral = lexer.stringVal();DefaultJSONParser _parser = new DefaultJSONParser(stringLiteral, parser.getConfig());BitSet bitSet =  deserialze(_parser, type, null);lexer.nextToken(JSONToken.COMMA);return (T) bitSet;}case  JSONToken.HEX:{byte[] bytes = lexer.bytesValue();lexer.nextToken(JSONToken.COMMA);return (T) BitSet.valueOf(bytes);}        	case  JSONToken.LBRACKET:{long[] longs = longArrayCodec.deserialze(parser, long[].class, null);return (T) BitSet.valueOf(longs);}case JSONToken.LBRACE:{lexer.nextToken();BitSet bitSet = new BitSet();while(lexer.token() != JSONToken.RBRACE) {if (lexer.token() == JSONToken.COMMA) {lexer.nextToken();continue;}Integer bitIndex = IntegerCodec.instance.deserialze(parser, Integer.class, null);if(null != bitIndex) {bitSet.set(bitIndex);}}lexer.nextToken(JSONToken.COMMA);return (T) bitSet ;}default: {Long value = LongCodec.instance.deserialze(parser, Long.class, null);return (T) BitSet.valueOf(new long[] {value});}}}@Overridepublic int getFastMatchToken() {return JSONToken.LBRACKET;}/** 序列化实现 */@Overridepublic void write(JSONSerializer serializer, Object object, Object fieldName, Type fieldType, int features)throws IOException {if (null==object || ! (object instanceof BitSet)) {serializer.writeNull();}SerializeWriter out = serializer.out;BitSet bitSet = (BitSet)object;switch(bitSetSerializeType) {case ARRAY:PrimitiveArraySerializer.instance.write(serializer, bitSet.toLongArray(), fieldName, fieldType, features);break;case TO_STRING:out.write(bitSet.toString());break;case HEX:out.writeHex(bitSet.toByteArray());break;default:break;}}public BitSetFastjsonCodec bitSetSerializeType(BitSetSerializeType bitSetSerializeType) {if(null != bitSetSerializeType) {this.bitSetSerializeType = bitSetSerializeType;}return this;}/*** {@link BitSet}序列化字符类型* @author guyadong**/public enum BitSetSerializeType{/** []整数数组 */ARRAY,/** {}包含的整数序列 */TO_STRING,/** 十六进制字符串 */HEX}
}

测试及调用示例:

	@Testpublic void test3FastjsonCodec() {try {SerializeConfig.globalInstance.put(BitSet.class, BitSetFastjsonCodec.INSTANCE );ParserConfig.global.putDeserializer(BitSet.class, BitSetFastjsonCodec.INSTANCE);BitSet bitSet = BitSet.valueOf(new byte[] {27,30});log("{}",bitSet);{/** 序列化为数组 */ BitSetFastjsonCodec.INSTANCE.bitSetSerializeType(ARRAY) ;String json = JSON.toJSONString(bitSet);log("JSON:{}",json);assertTrue(json.equals("[7707]"));BitSet parsed = JSON.parseObject(json, BitSet.class);assertTrue(bitSet.equals(parsed));}{/** 序列化为BASE64字符串 */ BitSetFastjsonCodec.INSTANCE.bitSetSerializeType(HEX) ;String json = JSON.toJSONString(bitSet);log("JSON:{}",json);assertTrue(json.equals("x'1B1E'"));BitSet parsed = JSON.parseObject(json, BitSet.class);assertTrue(bitSet.equals(parsed));}{/** 序列化为{}包含的整数序列 */ BitSetFastjsonCodec.INSTANCE.bitSetSerializeType(TO_STRING) ;String json = JSON.toJSONString(bitSet);log("JSON:{}",json);assertTrue(json.equals("{0, 1, 3, 4, 9, 10, 11, 12}"));BitSet parsed = JSON.parseObject(json, BitSet.class);assertTrue(bitSet.equals(parsed));}} catch (Throwable e) {e.printStackTrace();fail();}}

完整实现代码参见码云仓库:https://gitee.com/l0km/sql2java/blob/dev/sql2java-base/src/main/java/gu/sql2java/json/BitSetFastjsonCodec.java
完整测试代码参见码云仓库:https://gitee.com/l0km/sql2java/blob/dev/sql2java-base/src/test/java/gu/sql2java/BitSetJsonCodecTest.java

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/763688.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaScript 箭头函数

1.什么是箭头函数 箭头函数是ES6新定义函数的语法  语法&#xff1a;(参数)>函数体 传统函数&#xff1a; let sum function(a,b){return ab;} 箭头函数 let sum(a,b)>{return ab;} 2.箭头函数的用法 2.1省略保函参数的小括号 如果只有一个参数&#xff0c;参数小括号…

【JavaScript】NPM常用指令指南

河水清清弯又长 姑娘水边浣霓裳 清风卷过白云旁 飞鸟载来春花香 河水清清弯又长 姑娘水边浣霓裳 清风卷过白云旁 朝霞换夕阳 重逢是梦乡 春潮悠悠送波浪 石桥湾下小舟荡 此去经年谁如常 难得人间笑一场 春潮悠悠送波浪 石桥湾下小舟荡 此去经年谁如常 故人心头上 地久天又长 …

Word文档密码设置:Python设置、更改及移除Word文档密码

给Word文档设置打开密码是常见的Word文档加密方式。为Word文档设置打开密码后&#xff0c;在打开该文档时&#xff0c;需要输入密码才能预览及编辑&#xff0c;为Word文档中的信息提供了有力的安全保障。如果我们需要对大量的Word文档进行加密、解密处理&#xff0c;Python是一…

1. Java基础入门

1. Java基础入门 1.1 Java介绍(了解) 1.1.1 Java背景 Java是美国 sun 公司&#xff08;Stanford University Network&#xff09;在1995年推出的一门计算机高级编程语言。Java 之父&#xff1a;詹姆斯高斯林(James Gosling)。 2009年 sun公司被Oracle公司收购。Java公司图标…

大数据面试题 —— Zookeeper

目录 ZooKeeper 的定义ZooKeeper 的特点ZooKeeper 的应用场景你觉得Zookeeper比较重要的功能ZooKeeper 的选举机制 ***zookeeper主节点故障&#xff0c;如何重新选举&#xff1f;ZooKeeper 的监听原理 ***zookeeper集群的节点数为什么建议奇数台 ***ZooKeeper 的部署方式有哪几…

JAVA 栈和队列总结

除了最底层下面三个是实现类&#xff0c;其他都是接口。 双端队列&#xff08;队头队尾都可以插入和删除元素&#xff09;的方法&#xff1a; 普通队列方法&#xff1a; 常用的是add(),poll(), element() 我们用Deque(双端队列)实现栈 Deque当栈用的时候的方法。 deque.push…

利用WebGL绘制简单几何

利用WebGL绘制最简单的几何图形 一、WebGL简介 WebGL是一种用于在网页上渲染交互式3D和2D图形的JavaScript API。它基于OpenGL ES 2.0&#xff0c;提供了一种在浏览器中使用硬件加速图形的方式。 二、图形系统绘图流程 图形系统的通用绘图流程会包括六个部分&#xff1a; …

2024年【电工(初级)】考试内容及电工(初级)证考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 2024年【电工&#xff08;初级&#xff09;】考试内容及电工&#xff08;初级&#xff09;证考试&#xff0c;包含电工&#xff08;初级&#xff09;考试内容答案和解析及电工&#xff08;初级&#xff09;证考试练习…

C++中的类模板

C中的类模板 类模板 类模板在C中是一种非常强大的工具&#xff0c;它允许程序员编写与数据类型无关的代码。简单来说&#xff0c;类模板允许你定义一个蓝图&#xff0c;这个蓝图可以用来生成具体类型的类。使用类模板可以提高代码的复用性&#xff0c;减少重复代码&#xff0…

字节跳动春招研发部分编程题汇总做题笔记---Java

3.雀魂启动&#xff01; 小包最近迷上了一款叫做雀魂的麻将游戏&#xff0c;但是这个游戏规则太复杂&#xff0c;小包玩了几个月了还是输多赢少。 于是生气的小包根据游戏简化了一下规则发明了一种新的麻将&#xff0c;只留下一种花色&#xff0c;并且去除了一些特殊和牌方式&…

Java基础知识总结(14)

map集合 /* java.util.Map接口中常用的方法 1、Map和Collection 没有继承关系 2、Map集合以key和value的方式存储数据&#xff1a;键值对key和valuea都是引用数据类型key和value都是存储对象的内存地址key起到主导地位&#xff0c;value是key的一个附属品 3、Map接口中常用的方…

GDAL实现大幅影像的快速读取

这里做个备份&#xff0c;原文链接 遥感影像小则几百兆&#xff0c;大则5,6GB&#xff0c;所以在使用GDAL进行图像读取时面临读写速度较慢的问题&#xff0c;我们可以深入研究gdal中RasterIO函数的机制&#xff0c;发现该函数是通过一行一行读取影像来实现影像读入内存的&…

【教学类-40-01】20240322 幼儿视力检查照片合成GIF

作品展示——GIF动图 背景需求&#xff1a; 2024年3月22日&#xff0c;中班幼儿视力检查&#xff0c;保健老师表扬我们班幼儿视力正常率高。 我为每位孩子拍照时&#xff0c;突然想把动作图用Python变成GIF图片&#xff0c;于是每位孩子都拍了多张“辨认视力表的不同手势”&a…

基于Springboot的西安旅游系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的西安旅游系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&…

动态规划(算法竞赛、蓝桥杯)--单调队列优化绿色通道

1、B站视频链接&#xff1a;E45 单调队列优化DP 绿色通道_哔哩哔哩_bilibili #include <bits/stdc.h> using namespace std; const int N5e410; int n,tim,w[N],f[N],q[N];bool check(int m){int h1,t0;for(int i1; i<n; i){while(h<t && f[q[t]]>f[i-…

visual studio卸载几种方法

1、控制面板卸载&#xff1b; 2、有时候会发现控制面板卸载会失败&#xff0c;无法卸载&#xff0c;这时候要先把下面目录的关于visual studio的都删除&#xff0c;然后重启电脑后&#xff0c;重新安装vs即可。

使用echart绘制拓扑图,树类型,自定义tooltip和label样式,可收缩

效果如图&#xff1a; 鼠标移上显示 vue3 - ts文件 “echarts”: “^5.4.3”, import { EChartsOption } from echarts import * as echarts from echarts/core import { TooltipComponent } from echarts/components import { TreeChart } from echarts/charts import { C…

复试专业前沿问题问答合集10-1——区块链与加密货币

复试专业前沿问题问答合集10-1——区块链与加密货币 区块链与加密货币安全以及6G通信的基础知识问答: 区块链以及加密货币相关的基础安全知识 包括区块链如何确保交易安全、共识机制的作用、加密货币钱包的保护措施、智能合约的工作原理以及如何防范潜在的网络攻击。这些知…

vue项目实现---用户在页面没有操作5分钟时退出登录

方案1: 后端处理 (1)用户切换页面或者点击按钮时需要发送请求接口,如果后端判断在5分钟之内没有请求,然后将前端的token失效 方案2: 前端处理 (1)在main.js中创建全局的事件监听器来实现对键盘抬起事件和鼠标点击事件的监听 试例:Vue 项目中全局监听键盘抬起事件和鼠标点击…

【笔记】KaiOS SPN显示逻辑

更新流程code 1、gonk/dom/system/gonk/radio/RadioInterfaceLayer.jsm handleNetworkStateChanged -> requestNetworkInfo() -> handleRilResponse的getOperator -> handleOperator handleNetworkStateChanged:网络状态变化请求网络信息 this.requestNetworkInfo…