fastjson 序列化和反序列化 Map 排序问题

序列化

首先需要说明的一点,HashMap 是不能保证遍历输出顺序的,如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
Map<String, Object> map = new HashMap<>();
map.put("B", 2);
map.put("A", 1);
map.put("C", 3);
for (Map.Entry<String, Object> entry : map.entrySet()) {
System.out.println(entry.getKey());
}
// 输出:
A
B
C

Map<String, Object> map = new HashMap<>();
map.put("张三", 2);
map.put("李四", 1);
map.put("王五", 3);
for (Map.Entry<String, Object> entry : map.entrySet()) {
System.out.println(entry.getKey());
}
// 输出:
李四
张三
王五

如果要保证按插入顺序遍历可以使用 LinkedHashMap,如果要对 Key 排序输出可以使用 TreeMap。

JSON.toJSONString(map)方法序列化顺序是和 Map 本身的遍历顺序一致的:

1
2
3
4
5
6
7
8
9
10
11
12
13
// 按插入顺序
Map<String, Object> map = new LinkedHashMap<>();
map.put("B", 2);
map.put("A", 1);
map.put("C", 3);
System.out.println(JSON.toJSONString(map)); // {"B":2,"A":1,"C":3}

// 按 Key 排序
Map<String, Object> map = new TreeMap<>();
map.put("B", 2);
map.put("A", 1);
map.put("C", 3);
System.out.println(JSON.toJSONString(map)); // {"A":1,"B":2,"C":3}

所以 fastjson 的序列化顺序我们可以从 Map 本身入手。

反序列化

fastjson 的反序列化方法有个 TypeReference 参数,可以指定反序列化方式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
String str = "{\"B\":2,\"A\":1,\"C\":3}";

// 按输入顺序
Map<String, Object> map1 = JSON.parseObject(str, new TypeReference<LinkedHashMap<String, Object>>() {});
for (Map.Entry<String, Object> entry : map1.entrySet()) {
System.out.println(entry.getKey());
}
// 输出:
B
A
C

// 按 Key 排序
Map<String, Object> map2 = JSON.parseObject(str, new TypeReference<TreeMap<String, Object>>() {});
for (Map.Entry<String, Object> entry : map2.entrySet()) {
System.out.println(entry.getKey());
}
// 输出:
A
B
C