java無限遞歸遍歷json對象問題
需求
給一個json字符串,遍歷json字符串,輸出其每個key對應(yīng)的value。
舉一個例子
{
"a":1,
"b":{
"b1":2
}
}能夠輸出:
a->1;b.b1->2
上例只是為了說明問題舉得一個最簡單的json,實際應(yīng)用中json可以是嵌套非常復(fù)雜的結(jié)構(gòu)。
方案
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數(shù)組
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是數(shù)組
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結(jié)構(gòu)中key的路徑,此外對于數(shù)組接口,沒有輸出key。
對上面方法進行優(yōu)化:
static void analysisJson2(Object objJson,String flag) {
if(objJson instanceof JSONArray) {//如果obj為json數(shù)組
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);
//如果得到的是數(shù)組
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結(jié)構(gòu)中key的每個路徑都保存了下來。
但是,還是有一點點的小瑕疵,對于數(shù)組結(jié)構(gòu),沒有輸出下標值。
2、json-flatter庫
json-flatter庫可以將json結(jié)構(gòu)按照上面需求輸出,同時對于數(shù)組還能顯示下標。
例如:
{ "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}]總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
File.createTempFile創(chuàng)建臨時文件的示例詳解
這篇文章主要介紹了File.createTempFile創(chuàng)建臨時文件的示例詳解,在默認臨時文件目錄中創(chuàng)建一個空文件,使用給定前綴和后綴生成其名稱。 如果感興趣來了解一下2020-07-07
解析分別用遞歸與循環(huán)的方式求斐波那契數(shù)列的實現(xiàn)方法
本篇文章是對分別用遞歸與循環(huán)的方式求斐波那契數(shù)列的方法進行了詳細的分析介紹,需要的朋友參考下2013-06-06
Springboot實現(xiàn)根據(jù)條件切換注入不同實現(xiàn)類的示例代碼
這篇文章主要介紹了Springboot實現(xiàn)根據(jù)條件切換注入不同實現(xiàn)類的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
macOS下Spring Boot開發(fā)環(huán)境搭建教程
這篇文章主要為大家詳細介紹了macOS下Spring Boot開發(fā)環(huán)境搭建教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-01-01

