共计 2665 个字符,预计需要花费 7 分钟才能阅读完成。
介绍
通过分词和形象语法树生成后,咱们就能够依据语法树生成 java 对象,为了让程序尽量简略,object 用 Map 返回,array 用 List<Map> 返回,根本类型间接返回 value
实现
语法树到对象的生成绝对还是比较简单,首先咱们定义了一个总的入口函数
/**
* 将 json 生成 java 对象
*
* @param item
* @return
*/
public Object generate(Ast item) {if ("array".equals(item.getType())) {
// 返回数组对象
return generateList(item);
} else if ("object".equals(item.getType())) {
// 返回 object 对象
return generateObject(item);
} else if ("value".equals(item.getType())) {
// 根本类型 json 对象,比方 "100" 也是一个 json 对象
return item.getValue();}
return null;
}
对应三种类型的解决形式
generateObject
/**
* 生成 object 对象
*
* @param astItem
* @return
*/
public Map generateObject(Ast astItem) {
//object 对象以 Map 模式返回
Map<String, Object> object = new HashMap<>();
for (Ast ast : astItem.getItems()) {
Object value = null;
if ("object".equals(ast.getType()) || "array".equals(ast.getType())) {value = generate(ast);
} else if ("value".equals(ast.getType())) {value = ast.getValue();
}
object.put(ast.getName(), value);
}
return object;
}
- 遍历 object 的字段
- 如果是 object 或者 array,那么通过入口函数进行递归
- 如果是 value 间接取 value 值就行
generateList
/**
* 生成 object 对象数组
*
* @param item
* @return
*/
public List<Object> generateList(Ast item) {
// 数组对象以 List<Object> 模式返回
List<Object> result = new ArrayList<>();
for (Ast child : item.getItems()) {if ("object".equals(child.getType())) {result.add(generateObject(child));
} else if ("value".equals(child.getType())) {result.add(child.getValue());
} else if ("array".equals(child.getType())) {result.add(generateList(child));
}
}
return result;
}
- 遍历数组列表
- 如果是 object 进入对象处理函数
- 如果是 value 间接取值
- 如果是 array 递归进入数组处理函数
测试
咱们将生成的对象从新用 fastjson 变成 json 比照后果
public class Main {public static void main(String[] args) throws Exception {InputStream fin = Main.class.getResourceAsStream("/example.json");
byte[] buf = new byte[fin.available()];
fin.read(buf);
fin.close();
String json = new String(buf, "utf-8");
JSONParser parser = new JSONParser();
List<Token> tokens = parser.tokenizer(json);
tokens = parser.tokenClean(tokens);
List<Ast> astItems = parser.generateAST();
Ast ast = astItems.get(0);
Object object = parser.generate(ast);
System.out.println(String.format("|%-12s|%-12s|%-15s|", "type", "valueType", "value"));
System.out.println("-------------------------------------------");
for (Token t : tokens) {
System.out.println(String.format("|%-12s|%-12s|%-15s|",
t.getType(),
t.getValueType(),
t.getValue()));
}
System.out.println("-------------------------------------------");
System.out.println(JSON.toJSONString(ast, true));
System.out.println(JSON.toJSONString(object, true));
}
}
后果
{
"birthday":"1992-02-08",
"name":"asan",
"description":"a \"hudsom\"man",
"location":{
"area":"晋江市",
"province":"福建省",
"city":"泉州市"
},
"salary":1234.56,
"family":[
{
"name":"Helen",
"relation":"couple"
},
{
"name":"XiaoMan",
"relation":"daughter"
}
],
"married":true,
"age":32,
"tags":[
"coder",
"mid-age"
]
}
除了字段程序外其余数据都和原始的示例 json 一样,阐明后果是正确的,至此咱们实现了一个 json 解析器全副的工作。
代码
残缺代码请参考我的项目 https://github.com/wls1036/tiny-json-parser 的 0x04 分支
正文完