java无限递归遍历json对象问题
作者:赶路人儿
这篇文章主要介绍了java无限递归遍历json对象问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
需求
给一个json字符串,遍历json字符串,输出其每个key对应的value。
举一个例子
{ "a":1, "b":{ "b1":2 } }
能够输出:
a->1;b.b1->2
上例只是为了说明问题举得一个最简单的json,实际应用中json可以是嵌套非常复杂的结构。
方案
1、采用递归的方法打印每个路径上的值
static final String json_schema2 = "{\"a\":1,\"b\":{\"b1\":2},\"c\":[1,2,3,4],\"d\":{\"d1\":{\"d1_1\":100,\"d1_2\":101},\"d2\":[\"d2_1\",\"d2_2\"]},\"e\":[{\"e1\":1},{\"e2\":2}]}"; static void analysisJson(Object objJson){ //如果objJson为json数组 if(objJson instanceof JSONArray) { JSONArray objArray = (JSONArray)objJson; for (int i = 0; i < objArray.size(); i++) { analysisJson(objArray.get(i)); } } else if(objJson instanceof JSONObject) { //如果objJson为json对象 JSONObject jsonObject = (JSONObject)objJson; Iterator it = jsonObject.keySet().iterator(); while(it.hasNext()) { String key = it.next().toString(); Object value = jsonObject.get(key); //value if(value instanceof JSONArray) { //如果value是数组 JSONArray objArray = (JSONArray)value; analysisJson(objArray); } else if(value instanceof JSONObject){ //如果value是json对象 analysisJson((JSONObject)value); } else { //如果value是基本类型 System.out.println("["+key+"]:"+value.toString()+" "); } } } else { //objJson为基本类型 System.out.println(objJson.toString()+" "); } }
输出:
[a]:1
[b1]:2
1
2
3
4
[d1_1]:100
[d1_2]:101
d2_1
d2_2
[e1]:1
[e2]:2
上面的方法虽然可以输出json对象中的每个值,但是丢失了json结构中key的路径,此外对于数组接口,没有输出key。
对上面方法进行优化:
static void analysisJson2(Object objJson,String flag) { if(objJson instanceof JSONArray) {//如果obj为json数组 JSONArray objArray = (JSONArray)objJson; for (int i = 0; i < objArray.size(); i++) { analysisJson2(objArray.get(i),flag); } } else if(objJson instanceof JSONObject){//如果为json对象 JSONObject jsonObject = (JSONObject)objJson; Iterator it = jsonObject.keySet().iterator(); while(it.hasNext()) { String key = it.next().toString(); Object object = jsonObject.get(key); //如果得到的是数组 if(object instanceof JSONArray){ JSONArray objArray = (JSONArray)object; String path = ""; if (StringUtils.isNotBlank(flag)) { path = flag + "." + key; } else { path = key; } analysisJson2(objArray,path); } else if(object instanceof JSONObject) {//如果key中是一个json对象 String path = ""; if (StringUtils.isNotBlank(flag)) { path = flag + "." + key; } else { path = key; } analysisJson2((JSONObject)object,path); } else {//如果key中是其他 String path = ""; if (StringUtils.isNotBlank(flag)) { path = flag + "." + key; } else { path = key; } System.out.println(path+":"+object.toString()+" "); } } } else {//如果key中是其他 System.out.println(flag+":"+objJson.toString()+" "); } }
输出:
a:1
b.b1:2
c:1
c:2
c:3
c:4
d.d1.d1_1:100
d.d1.d1_2:101
d.d2:d2_1
d.d2:d2_2
e.e1:1
e.e2:2
非常完美,吧json结构中key的每个路径都保存了下来。
但是,还是有一点点的小瑕疵,对于数组结构,没有输出下标值。
2、json-flatter库
json-flatter库可以将json结构按照上面需求输出,同时对于数组还能显示下标。
例如:
{ "a": { "b": 1, "c": null, "d": [false, true] }, "e": "f", "g": 2.3 } //输出 { "a.b": 1, "a.c": null, "a.d[0]": false, "a.d[1]": true, "e": "f", "g": 2.3 }
示例:
<dependency> <groupId>com.github.wnameless.json</groupId> <artifactId>json-flattener</artifactId> <version>0.9.0</version> </dependency>
String json = "{ \"a\" : { \"b\" : 1, \"c\": null, \"d\": [false, true] }, \"e\": \"f\", \"g\":2.3 }"; Map<String, Object> flattenJson = JsonFlattener.flattenAsMap(json); System.out.println(flattenJson); // Output: {a.b=1, a.c=null, a.d[0]=false, a.d[1]=true, e=f, g=2.3} String jsonStr = JsonFlattener.flatten(json); System.out.println(jsonStr); // Output: {"a.b":1,"a.c":null,"a.d[0]":false,"a.d[1]":true,"e":"f","g":2.3} String nestedJson = JsonUnflattener.unflatten(jsonStr); System.out.println(nestedJson); // {"a":{"b":1,"c":null,"d":[false,true]},"e":"f","g":2.3} // Support JSON keys which contain dots or square brackets String flattendJsonWithDotKey = JsonFlattener.flatten("[{\"a.a.[\":1},2,{\"c\":[3,4]}]"); System.out.println(flattendJsonWithDotKey); // Output: {"[0][\"a.a.[\"]":12,"[1]":2,"[2].c[0]":3,"[2].c[1]":4} String nestedJsonWithDotKey = JsonUnflattener.unflatten( "{\"[1][0];\":2,\"[0]\":1,\"[1][1]\":3,\"[2]\":4,\"[3][\\\"ab.c.[\\\"]\":5}"); System.out.println(nestedJsonWithDotKey); // Output: [1,[2,3],4,{"ab.c.[":5}]
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。