FastJson遇见的问题或项目实战中优化的问题,看源码都可以解决
1:感觉见鬼了一般存储JSONObject中的字段竟然不见了?
JSONObject object=new JSONObject();
Map fields = new HashMap();
fields.put("1","1");
object.put("fields",fields);
System.out.println(object.toString());
JSONObject newFields = object.getJSONObject("fields");
newFields.put("2",2);
//TODO 序列化字符串没有2?!!
// 看源码便可以知晓,当我们使用Map当做JSONObject解析时候,Fastjson会返回一个新的对象
System.out.println(object.toString());
com.alibaba.fastjson.JSON#toJSON(java.lang.Object, com.alibaba.fastjson.serializer.SerializeConfig)源码:
public static Object toJSON(Object javaObject, SerializeConfig config) {
if (javaObject == null) {
return null;
}
if (javaObject instanceof JSON) {
return javaObject;
}
if (javaObject instanceof Map) {
Map<Object, Object> map = (Map<Object, Object>) javaObject;
// 创建了一个新的JSONObject返回了
JSONObject json = new JSONObject(map.size());
for (Map.Entry<Object, Object> entry : map.entrySet()) {
Object key = entry.getKey();
String jsonKey = TypeUtils.castToString(key);
Object jsonValue = toJSON(entry.getValue());
json.put(jsonKey, jsonValue);
}
return json;
}
2:当我们使用JSONArray时候,有些时候里面可能存储较大量的数据,但是有些场景需要在指定index处进行insert操作,这时由于JSONArray默认底层使用的是ArrayList存储,因此存在性能问题,那么是否可以使用LinkedList呢?答案可以的:
JSONArray arr = new JSONArray(new LinkedList());
3:当我们查询接口获取到一个JSONArray字符串想反序列化时候可否将底层存储的ArrayList使用LinkedList替换呢?答案:可以,修改一下源码或者添加一个重载方法即可。
public static JSONArray parseArray(String text) {
if (text == null) {
return null;
}
DefaultJSONParser parser = new DefaultJSONParser(text, ParserConfig.getGlobalInstance());
JSONArray array;
JSONLexer lexer = parser.lexer;
if (lexer.token() == JSONToken.NULL) {
lexer.nextToken();
array = null;
} else if (lexer.token() == JSONToken.EOF) {
array = null;
} else {
// array = new JSONArray(new ArrayList());
array = new JSONArray(new LinkedList());
parser.parseArray(array);
parser.handleResovleTask(array);
}
parser.close();
return array;
}
4:当我们调用方法返回一个含有大量的元素的JSONArray时候该如何进行插入?
问题3中的是字符串我们解析时候可以自定义解析为LinkedList,但是当我们获取的是一个JSONArray时候该如何处理?难道还有序列化字符串在反序列化到底层存储为LinkedList的JSONArray吗?答案不需要,我们可以借助java的System的arrcopy方法高效完成转换:
//加入我们有一个比较大的list,想在中间高效插入元素
List<Integer> list = Lists.newArrayList(1, 2, 3, 5);//Lists来至于Guava
Integer[] iarr = new Integer[5]; // 相比如add(index,e)耗费时间位置所在
//对于顺序存储的ArrayList而言,toArray方法的底层实现也是使用的System.arrcopy方法进行高效生成数组
Integer[] arr1 = list.toArray(new Integer[0]);
Integer[] arr2 = new Integer[]{1, 2, 3};
//TODO 高效复制
System.arraycopy(arr1, 0, iarr, 0, 3);
//模拟中间插入元素
iarr[3] = 4;
//TODO 高效复制
System.arraycopy(arr1, 3, iarr, 4, 1);
//java.util.Arrays.ArrayList
// Arrays的asList方法效率高,原因是直接将传入的数组作为Arrays.ArrayList的底层存储容器
List ret = Arrays.asList(iarr); System.out.println(ret.getClass());
JSONArray retArr = new JSONArray(ret);
System.out.println(JSON.toJSONString(retArr));
该点存在错误,经过实际测试发现该方案比ArraList的add(index,e)普遍要慢,原因首先还是看一下ArrayList的add(index,e)方法:
public void add(int index, E element) {
rangeCheckForAdd(index);
ensureCapacityInternal(size + 1); // Increments modCount!!
System.arraycopy(elementData, index, elementData, index + 1,
size - index);
elementData[index] = element;
size++;
}
看源码可以发现add(index,e)使用的也是arraycopy,那为什么要快呢?认真看arraycopy的参数都是elementData,而且该数组通常容量都是已经扩容好的,在极有少数情况下需要扩容。但是上述4中的方法需要我们自己初始化一个数组,该数组大小等于current+addSize,初始化该数组比较耗费时间。
注意: JDK的ArrayList扩容使用的是内存复制,并不是逐个移动元素。JDK开发者还是很聪明的。
5:在4中我们可以发现使用素组高效创建ArrayList的方法时:
List ret = Arrays.asList(1,2,3,4);
底层不是进行for循环逐个插入,而是直接使用数组作为ArrayList的底层存储。
但是需要特别注意:
此处的ArrayList不是java.util.ArrayList,而是class java.util.Arrays.ArrayList 。但是class java.util.Arrays.ArrayList也是java.util.List的子类实现,由于java多态存在因此不存在类型的限制。
6: 同于顺序存储的ArrayList的toArray方法底层使用的是内存复制生成数组,高效率。
FastJson遇见的问题或项目实战中优化的问题,看源码都可以解决的更多相关文章
- 李炎恢bootstarp_项目实战__瓢城企业(注释+源码)
源代码下载地址:http://pan.baidu.com/s/1gfI9Pj9 /********************************* pc界面设备页面***************** ...
- 痞子衡嵌入式:在SBL项目实战中妙用i.MXRT1xxx里SystemReset不复位的GPR寄存器
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT1xxx里SystemReset不复位的GPR寄存器的小妙用. 我们知道稍大规模的项目代码设计一般都是多人协作完成的,在项目 ...
- net core体系-web应用程序-4asp.net core2.0 项目实战(1)-2项目说明和源码下载
本文目录1. 摘要2. Window下运行 3.linux下运行4. 开发记录5. 总结 1.概要 写<Asp.Net Core 2.0 项目实战>系列断断续续已经很长时间了,期间很多朋友 ...
- python3-开发进阶 django-rest framework 中的 版本操作(看源码解说)
今天我们来说一说rest framework 中的 版本 操作的详解 首先我们先回顾一下 rest framework的流程: 请求进来走view ,然后view调用视图的dispath函数 为了演示 ...
- 在eclipse中查看HttpServlet源码失败的解决方法
在初次建立java EE 项目时,想要查看HttpServlet源码时会提示失败, 按照网上的方式,将Tomcat中lib中的servlet-api.jar的包导进去,发现并不管用.并且提示里面并不包 ...
- Fabric2.2中的Raft共识模块源码分析
引言 Hyperledger Fabric是当前比较流行的一种联盟链系统,它隶属于Linux基金会在2015年创建的超级账本项目且是这个项目最重要的一个子项目.目前,与Hyperledger的另外几个 ...
- Handlebars模板引擎中的each嵌套及源码浅读
若显示效果不佳,可移步到愚安的小窝 Handlebars模板引擎作为时下最流行的模板引擎之一,已然在开发中为我们提供了无数便利.作为一款无语义的模板引擎,Handlebars只提供极少的helper函 ...
- 怎么在Mac中的Safari查看网页源码
一般情况下,Safari中右键是没有查看网页源文件这个选项的: 但是通过设置是可以看到的~ 1.首先找到电脑左上角的Safari然后选择偏好设置: 2.接着选择 “高级”页签,勾选最下面的 “在菜单栏 ...
- Eclipse项目里面看源码和文档
Eclipse项目里面看源码 1.新建项目列表 2.进入struts2-core-2.3.20.jar,双击之后,看不到源码 3.右键struts2-core-2.3.20.jar,选择propert ...
随机推荐
- Java - “JUC”锁
[Java并发编程实战]-----“J.U.C”:锁,lock 在java中有两种方法实现锁机制,一种是在前一篇博客中([java7并发编程实战]-----线程同步机制:synchronized) ...
- Angular4.x 自定义搜索组件
Angular4 随笔(三) ——自定义搜索组件 1.简介 本组件主要是实现了搜索功能,主要是通过父子组件传值实现. 基本逻辑: 1.创建一个搜索组件,如:ng g component searc ...
- IE8中jQuery.load()加载页面不显示的原因
一.jQuery.load() jQuery.load(url,[data],[callback])通过Ajax异步请求加载服务器中的数据,并把数据放到指定元素中. url :请求服务器的地址 dat ...
- Intellij IDEA 使用GitHub+Git
1.配置Git路径 打开Settings(File-->Settings) --> 在搜索栏内输入git,回车跳转到Git配置页面 --> 将git的运行路径填入Path to Gi ...
- 设计模式原则(5)--Law of Demeter(LoD)--迪米特法则
作者QQ:1095737364 QQ群:123300273 欢迎加入! 1.定义: 一个软件实体应当尽可能少地与其他实体发生相互作用.也就是说:一个类对自己依赖的类知道的越少越好.也就是 ...
- vue+webpack+vue-cli+WebStrom 项目搭建
作者QQ:1095737364 QQ群:123300273 欢迎加入! 1.安装 webpack 和vue-cli 模块: npm install webpack -g npm in ...
- eclipse java web项目经常自动调试进入debug模式
今天在运行Javaweb项目时,程序运行运行着就自动调试进入ThreadpoolExecutor,看着非常影响心情.最后在网上搜解决方法最后找到原因,解决方法如下. Window——>Prefe ...
- bower 和 npm 的区别详细介绍
摘要: 本文讲的是bower 和 npm 的区别详细介绍, 简单的说,npm是进行后端开发中,使用的模块安装工具,而bower,是前端的模块安装工具. 比如,在安装express,socket.io时 ...
- 图像增强算法(直方图均衡化、拉普拉斯、Log、伽马变换)
一.图像增强算法原理 图像增强算法常见于对图像的亮度.对比度.饱和度.色调等进行调节,增加其清晰度,减少噪点等.图像增强往往经过多个算法的组合,完成上述功能,比如图像去燥等同于低通滤波器,增加清晰度则 ...
- 位图和SVG用法比较
位图,亦称为点阵图像或绘制图像,是由称作像素(图片元素)的单个点组成的.这些点可以进行不同的排列和染色以构成图样.当放大位图时,可以看见赖以构成整个图像的无数单个方块.扩大位图尺寸的效果是增大单个像素 ...