将JSON对象转化为对象是开发中的常规和通用操作。为了提高开发效率,经常会用到第三方的json处理类库,其中Fastjson就是流行的JSON处理类库之一。
在最近一次使用中,我遇到了一个问题。JSON转换为Map后,顺序发生了变化,导致依赖于参数顺序的操作无法正常执行。
这个问题的解决方案如下:
string jsonStr=' { \ ' J2 ' : ' A \ ',\ ' J1 \ ' : \ ' B \ ',\ ' listMap ' :[{ \ ' I2 ' : ' C \ ',\ ' I1 ' : ' D \ ',\ ' I3 ' : ' E \ ' } } ' } ';
对象jsonMap=JSON . parseobject(jsonStr,Map.class,Feature。ordered field);
00-1010在之前的开发中,JSON在转换为实体对象时,并不需要关心转换对象的顺序,所以也没有深究顺序变化的原因。既然你遇到了这个问题,请检查一下原因。
{'J2' :' a ',' J1' :' b ',' listmap' : [{'I2' :' c ',' i1' 3360' d ',' i3' 3360' e'}]}比如上面的JSON。
string jsonStr=' { \ ' J2 ' : ' A \ ',\ ' J1 \ ' : \ ' B \ ',\ ' listMap ' :[{ \ ' I2 ' : ' C \ ',\ ' I1 ' : ' D \ ',\ ' I3 ' : ' E \ ' } } ' } ';
MapString,Object jsonMap=JSON . parseobject(jsonStr,map . class);转换后的地图排列顺序如下:
地图中的键顺序不正确。
出现这个问题时,首先想到的是,Fastjson转换Map时,实例化的Map是HashMap,HashMap本身有默认的排序算法(根据hashcode值排序)。因此,将转换模式更改为以下代码,并使用LinkedHashMap转换JSON:
string jsonStr=' { \ ' J2 ' : ' A \ ',\ ' J1 \ ' : \ ' B \ ',\ ' listMap ' :[{ \ ' I2 ' : ' C \ ',\ ' I1 ' : ' D \ ',\ ' I3 ' : ' E \ ' } } ' } ';
MapString,Object jsonMap=JSON . parseobject(jsonStr,linkedhasmap . class);最终的运行结果如下:只有外部的Key是相同的顺序,但是内部的嵌套集在转换时仍然是错误的顺序。
内部列表映射的键顺序仍然错误。
最后,跟踪代码发现在Fastjson的==DefaultJsonParser==类下,转换内层的json仍然会实例化一个Map对象,如下代码所示:
public JSON object(int initial capacity,布尔有序){ 0
如果(已订购){ 0
this . map=new LinkedHashMap(initial capacity);
} else {
this . map=new HashMap(initial capacity);
}
}默认情况下,}JSONObject构造函数的ordered参数为false,默认情况下会实例化HashMap,因此内存嵌套仍然是非固定顺序的。
因此,您只需将其更改为ordered=true,即可使用LinkedHashMap实例化地图对象。最终找到了解决这个问题的办法。
* *在使用Fastjson之前,我们没有深入探索更多的函数。现在我们发现有一个名为Feature的枚举对象,用来扩展Fastjson的功能。功能的详细使用规则将在后面研究。**