Sorry, your browser cannot access this site
This page requires browser support (enable) JavaScript
Learn more >

主要实现思路是递归。我们把单个值也当作合法的json,先判断当前json类型,如果是单个值就直接return对应类型(解析时)或toString(编码时),如果是Object就遍历它的key值,然后取冒号后面的部分递归解析/编码,Array也差不多。
经解码再编码测试非常完美。
img

知识点:java泛型类如HashMap<String, Object>无法用instanceof检测。
但是,可以新写一个空类去继承他,这样就不是泛型了。

(Java快加个rust那种枚举吧)

Warning有点多,将就看

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
package fun.zhufn.oldcomm;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

class BadJsonException extends RuntimeException {
}

class JsonMap extends HashMap<String, Object> {

}

class JsonList extends ArrayList<Object> {

}

public class MyJsonParser {
static void print(String s) {
System.out.println(s);
}
public static Object parse(String json) throws BadJsonException {
json = json.trim();
if (json.startsWith("[") && json.endsWith("]")) {
JsonList ret = new JsonList();
json = json.substring(1, json.length() - 1);
while(true) {
int p1 = 0, p2 = findNextComma(json), len = json.length();
String curLine = json.substring(p1, p2).trim();
ret.add(parse(curLine));

if (p2 < len) json = json.substring(p2 + 1);
else break;
}
return ret;
} else if (json.startsWith("{") && json.endsWith("}")) {
return nextObject(json);
} else if (json.startsWith("\"") && json.endsWith("\"")) {
int cnt = 0;
for (int i = 0; i < json.length(); ++i) {
if (json.charAt(i) == '"' && (i > 0 && json.charAt(i - 1) != '\\')) {
++cnt;
}
}
if (cnt > 2) throw new BadJsonException();
return json.substring(1, json.length() - 1);
} else if (json.equals("true")) {
return true;
} else if (json.equals("false")) {
return false;
} else {
try {
return Double.parseDouble(json);
} catch (Exception e) {
throw new BadJsonException();
}
}
}

private static JsonMap nextObject(String json) throws BadJsonException {
JsonMap ret = new JsonMap();
if (!json.startsWith("{") || !json.endsWith("}")) {
throw new BadJsonException();
}
json = json.substring(1, json.length() - 1);
if (json.isEmpty()) return ret;
while(true) {
int p1 = 0, p2 = findNextComma(json), len = json.length();
String curLine = json.substring(p1, p2).trim();
if (curLine.startsWith("\"")) {
int j = stringPos(curLine);
String key = curLine.substring(1, j);
curLine = curLine.substring(j + 1).trim();
if (!curLine.startsWith(":")) throw new BadJsonException();
ret.put(key, parse(curLine.substring(1).trim()));
} else {
throw new BadJsonException();
}
if (p2 < len) json = json.substring(p2 + 1);
else break;
}
return ret;
}

private static int intPos(String str) throws BadJsonException {
int i = -1;
while (i + 1 < str.length() &&str.charAt(i + 1) >= '0' && str.charAt(i + 1) <= '9') {
++i;
}
if (i == -1) {
throw new BadJsonException();
}
return i;
}

private static int stringPos(String str) throws BadJsonException {
if (!str.startsWith("\"")) {
throw new BadJsonException();
}
int i = 1;
while (i < str.length()) {
if (str.charAt(i) == '"') {
break;
}
++i;
}
if (i == str.length()) throw new BadJsonException();
return i;
}

private static int findNextComma(String json) throws BadJsonException {
int quoteCnt = 0, squareBracketsCnt = 0, bracesCnt = 0;
int len = json.length();
int i = 0;
while (i < len) {
if (json.charAt(i) == ',' && quoteCnt % 2 == 0 && squareBracketsCnt == 0 && bracesCnt == 0) {
break;
}
if (json.charAt(i) == '"') {
++quoteCnt;
}
if (json.charAt(i) == '[') {
++squareBracketsCnt;
}
if (json.charAt(i) == '{') {
++bracesCnt;
}
if (json.charAt(i) == ']') {
--squareBracketsCnt;
}
if (json.charAt(i) == '}') {
--bracesCnt;
}
++i;
}
return i;
}

public static String gen(Object data) {
if (data instanceof JsonMap) {
StringBuilder ret = new StringBuilder("{");
JsonMap mp = (JsonMap)data;
for (String key: mp.keySet()) {
ret.append("\"").append(key).append("\":");
ret.append(gen(mp.get(key)));
ret.append(",");
}
ret.delete(ret.length() - 1, ret.length());
ret.append("}");
return ret.toString();
} else if (data instanceof JsonList) {
StringBuilder ret = new StringBuilder("[");
for (Object v: (JsonList)data) {
ret.append(gen(v));
ret.append(",");
}
ret.delete(ret.length() - 1, ret.length());
ret.append("]");
return ret.toString();
} else if (data instanceof String) {
return "\"" + data + "\"";
} else {
return data.toString();
}
}

public static void main(String []args) {
//这是一组测试数据,应该没人来开我盒
print(gen(parse("""
{"code":0,"message":"0","ttl":1,"data":{"isLogin":true,"email_verified":1,"face":"http://i1.hdslb.com/bfs/face/97c86ea7c397f91b1a858737d06e73859d2d86f5.jpg","face_nft":0,"level_info":{"current_level":6,"current_min":28800,"current_exp":31365,"next_exp":"--"},"mid":39100231,"mobile_verified":1,"money":85,"moral":70,"official":{"role":0,"title":"","desc":"","type":-1},"officialVerify":{"type":-1,"desc":""},"pendant":{"pid":6053,"name":"星尘","image":"http://i1.hdslb.com/bfs/garb/item/92d63a9014d4f0b2cefaef64f757162f750c7ad0.png","expire":0,"image_enhance":"http://i1.hdslb.com/bfs/garb/item/92d63a9014d4f0b2cefaef64f757162f750c7ad0.png","image_enhance_frame":""},"scores":0,"uname":"BuringStraw","vipDueDate":1668355200000,"vipStatus":1,"vipType":2,"vip_pay_type":0,"vip_theme_type":0,"vip_label":{"path":"","text":"年度大会员","label_theme":"annual_vip","text_color":"#FFFFFF","bg_style":1,"bg_color":"#FB7299","border_color":""},"vip_avatar_subscript":1,"vip_nickname_color":"#FB7299","vip":{"type":2,"status":1,"due_date":1668355200000,"vip_pay_type":0,"theme_type":0,"label":{"path":"","text":"年度大会员","label_theme":"annual_vip","text_color":"#FFFFFF","bg_style":1,"bg_color":"#FB7299","border_color":""},"avatar_subscript":1,"nickname_color":"#FB7299","role":3,"avatar_subscript_url":"http://i0.hdslb.com/bfs/vip/icon_Certification_big_member_22_3x.png"},"wallet":{"mid":39100231,"bcoin_balance":1,"coupon_balance":0,"coupon_due_time":0},"has_shop":false,"shop_url":"","allowance_count":0,"answer_status":0,"is_senior_member":1}}""")));
}
}

评论