遍历JSONObject、JSONArray (适用任意复杂结构类型)

遍历JSONObject、JSONArray (适用任意复杂结构类型)

多数时候,我们可能只需要获取JSONObject里的某个键值对,但有时候,我们需要遍历整个JSONObject对象。

本文用的是alibaba的fastjson,如果没有用过fastjson,可以在pom.xml里添加下面的依赖。

com.alibaba

fastjson

1.2.24

先说简单的JSONObject对象,类似下面这种。

{

"username": "陆仁甲",

"age": "24",

"height": "170cm",

"weight": "180斤",

"hobby": "宅"

}

就是一个普通的用户信息,只有几个简单的属性,一看内容,就知道这个人肯定是个臭屌丝。那么我们现在就写代码遍历一下这个臭屌丝的信息。

public static void main(String[] args) {

/*

需要说明一下,带格式的json字符串和不带格式的json字符串都一样能解析成JSONObject。

这里为了看的比较直观,我就使用了带格式的json字符串。

*/

// 原始json格式的字符串。不带格式。

// String originalStr = "{\"username\": \"陆仁甲\",\"age\": \"24\",\"height\": \"170\",\"weight\": \"180\",\"hobby\": \"宅\"}";

// 原始json格式的字符串。带格式。

String originalStr = "{\n" +

"\t\"username\": \"陆仁甲\",\n" +

"\t\"age\": \"24\",\n" +

"\t\"height\": \"170cm\",\n" +

"\t\"weight\": \"180斤\",\n" +

"\t\"hobby\": \"宅\"\n" +

"}";

JSONObject jsonObject = JSON.parseObject(originalStr);

for (Map.Entry entry : jsonObject.entrySet()) {

System.out.println(entry.getKey() + " : " + entry.getValue());

}

}

打印结果:

weight : 180斤 age : 24 username : 陆仁甲 height : 170cm hobby : 宅

这样我们就完成了对JSONObject对象的遍历,是不是超级简单!

细心的同学可能会发现,这个遍历方式跟遍历Map不是一模一样的吗?

确实,一模一样。因为JSONObject其实本来就是一个Map。深入源码,我们可以看一下JSONObject的声明。

public class JSONObject extends JSON implements Map, Cloneable, Serializable, InvocationHandler

看到没,JSONObject是一个实现了Map的类。

我们再看,JSONObject里面有这样一个属性: private final Map map;

我们平时调用put方法往JSONObject对象里面存键值对,其实就是存进了这个map里面,同样,取也是从这个map里面取。这两个方法的源码如下:

public Object put(String key, Object value) {

return map.put(key, value);

}

public Object get(Object key) {

return map.get(key);

}

这下,你明白了为什么可以跟遍历Map一样遍历JSONObject了吧,并且对JSONObject对象的存取也有了更深的认识了吧。

如果想了结更多的东西,那就自己去看源码吧。

在实际开发中,如果我们拿到的就是一个JSONObject,那么就不需要把json格式的字符串解析成JSONObject这一步了。不过,大多数的情况下,我们和其它系统交互,拿到的通常都是一个json格式的字符串。如果是字符串形式,多一步解析操作就行了。

如果到这里,能够解决你的问题,那再好不过了。不过有时候,需求总是千变万化。

对于一个臭屌丝,信息比较简单,遍历起来自然就像上面那样简单。但是如果,我们拿到是一个复杂对象的信息,如下面这样。一看就是个超级有钱人。

{

"基本信息": {

"username": "王多鱼",

"age": "36",

"height": "175cm",

"weight": "150斤",

"hobby": "花钱"

},

"房产": {

"address": "西虹市朱雀路888弄",

"area": "220平米",

"price": "20000000元"

}

}

其实这种也很容易遍历,一个一个遍历就好了。

public static void main(String[] args) {

String originalStr = "{\n" +

"\t\"基本信息\": {\n" +

"\t\t\"username\": \"王多鱼\",\n" +

"\t\t\"age\": \"36\",\n" +

"\t\t\"height\": \"175cm\",\n" +

"\t\t\"weight\": \"150斤\",\n" +

"\t\t\"hobby\": \"花钱\"\n" +

"\t},\n" +

"\t\"房产\": {\n" +

"\t\t\"address\": \"西虹市朱雀路888弄\",\n" +

"\t\t\"area\": \"220平米\",\n" +

"\t\t\"price\": \"20000000元\"\n" +

"\t}\n" +

"}\n";

JSONObject jsonObject = JSON.parseObject(originalStr);

JSONObject baseInfo = jsonObject.getJSONObject("基本信息");

JSONObject house = jsonObject.getJSONObject("房产");

// 遍历基本信息

for (Map.Entry entry : baseInfo.entrySet()) {

System.out.println(entry.getKey() + " : " + entry.getValue());

}

System.out.println();

// 遍历房产信息

for (Map.Entry entry : house.entrySet()) {

System.out.println(entry.getKey() + " : " + entry.getValue());

}

}

打印结果如下:

weight : 150斤 age : 36 username : 王多鱼 height : 175cm hobby : 花钱

area : 220平米 address : 西虹市朱雀路888弄 price : 20000000元

总之,我们会遍历一个的,就会遍历2个的,3个的......

不过,现在又发生了变化,王多鱼觉得一个房子不够住,又买了一个,于是他的信息就又变成了下面这样。

{

"基本信息": {

"username": "王多鱼",

"age": "36",

"height": "175cm",

"weight": "150斤",

"hobby": "花钱"

},

"房产": [{

"address": "西虹市朱雀路888弄",

"area": "220平米",

"price": "20000000元"

},

{

"address": "西虹市龙门路666弄",

"area": "356平米",

"price": "40000000元"

}

]

}

不就是多了一套房,JSONObject对象里面又引入了一个数组吗,虽然涉及JSONArray 的遍历,看着复杂了一点,但是依然很简单。

public class JsonTest {

public static void main(String[] args) {

String originalStr = "{\n" +

"\t\"基本信息\": {\n" +

"\t\t\"username\": \"王多鱼\",\n" +

"\t\t\"age\": \"36\",\n" +

"\t\t\"height\": \"175cm\",\n" +

"\t\t\"weight\": \"150斤\",\n" +

"\t\t\"hobby\": \"花钱\"\n" +

"\t},\n" +

"\t\"房产\": [{\n" +

"\t\t\t\"address\": \"西虹市朱雀路888弄\",\n" +

"\t\t\t\"area\": \"220平米\",\n" +

"\t\t\t\"price\": \"20000000元\"\n" +

"\t\t},\n" +

"\t\t{\n" +

"\t\t\t\"address\": \"西虹市龙门路666弄\",\n" +

"\t\t\t\"area\": \"356平米\",\n" +

"\t\t\t\"price\": \"40000000元\"\n" +

"\t\t}\n" +

"\t]\n" +

"}";

JSONObject jsonObject = JSON.parseObject(originalStr);

JSONObject baseInfo = jsonObject.getJSONObject("基本信息");

// 遍历基本信息

for (Map.Entry entry : baseInfo.entrySet()) {

System.out.println(entry.getKey() + " : " + entry.getValue());

}

System.out.println();

// 遍历数组。遍历房产信息。

JSONArray houseArray = jsonObject.getJSONArray("房产");

for (int i = 0; i < houseArray.size(); i++) {

System.out.println("遍历第" + (i+1) + "套房产");

JSONObject house = (JSONObject) houseArray.get(i);

for (Map.Entry entry : house.entrySet()) {

System.out.println(entry.getKey() + " : " + entry.getValue());

}

}

}

打印结果:

weight : 150斤 age : 36 username : 王多鱼 height : 175cm hobby : 花钱

遍历第1套房产 area : 220平米 address : 西虹市朱雀路888弄 price : 20000000元 遍历第2套房产 area : 356平米 address : 西虹市龙门路666弄 price : 40000000元

到这里,我们已经会遍历一个JSONObject对象,JSONObject对象里嵌套JSONObject对象,JSONObject对象里嵌套JSONObject对象和数组。我们已经很强大了。

到这里还没有结束。某天,王多鱼觉得一个人太孤单,想找个女朋友,于是,找了一个叫爱丽丝的女朋友,王多鱼的信息就又变成了下面这样的。

{

"基本信息": {

"username": "王多鱼",

"age": "36",

"height": "175cm",

"weight": "150斤",

"hobby": "花钱"

},

"房产": [{

"address": "西虹市朱雀路888弄",

"area": "220平米",

"price": "20000000元"

},

{

"address": "西虹市龙门路666弄",

"area": "356平米",

"price": "40000000元"

}

],

"女朋友": {

"name": "爱丽丝",

"age": "18",

"height": "165cm",

"weight": "95斤",

"skill": "钢琴,舞蹈"

}

}

某天,王多鱼觉得一个女朋友不够,不符合自己有钱人的身份,于是又找了一个叫安妮的女朋友,于是他的信息又变成了下面这样的。

{

"基本信息": {

"username": "王多鱼",

"age": "36",

"height": "175cm",

"weight": "150斤",

"hobby": "花钱"

},

"房产": [{

"address": "西虹市朱雀路888弄",

"area": "220平米",

"price": "20000000元"

}, {

"address": "西虹市龙门路666弄",

"area": "356平米",

"price": "40000000元"

}],

"女朋友": [{

"name": "爱丽丝",

"age": "18",

"height": "165cm",

"weight": "95斤",

"skill": "钢琴,舞蹈"

}, {

"name": "安妮",

"age": "20",

"height": "170cm",

"weight": "100斤",

"skill": "小提琴,唱歌,舞蹈"

}]

}

某天,王多鱼觉得女朋友不好玩,想养条狗......

某天,王多鱼的苹果手机坏了,听说刚出来的xx国产品牌还不错......

某天,王多鱼......

就这样,王多鱼的信息不停的变化。

当然了,我们也可以不停的修改代码来满足需求。

不过,这样维护起来太麻烦了。有没有那种,就是那种,真的很少见的那种,一个方法,到处运行的呢?

于是,打开浏览器,找呀找,哎呀,竟然找不到。找不到,就自己写吧。

package ztt.json;

import com.alibaba.fastjson.JSON;

import com.alibaba.fastjson.JSONArray;

import com.alibaba.fastjson.JSONObject;

/**

* @Description:

* @Auther: ztt

* @Date: 2020/2/20 23:05

*/

public class JsonTest {

public static void main(String[] args) {

String originalStr = "{\n" +

"\t\"基本信息\": {\n" +

"\t\t\"username\": \"王多鱼\",\n" +

"\t\t\"age\": \"36\",\n" +

"\t\t\"height\": \"175cm\",\n" +

"\t\t\"weight\": \"150斤\",\n" +

"\t\t\"hobby\": \"花钱\"\n" +

"\t},\n" +

"\t\"房产\": [{\n" +

"\t\t\"address\": \"西虹市朱雀路888弄\",\n" +

"\t\t\"area\": \"220平米\",\n" +

"\t\t\"price\": \"20000000元\"\n" +

"\t}, {\n" +

"\t\t\"address\": \"西虹市龙门路666弄\",\n" +

"\t\t\"area\": \"356平米\",\n" +

"\t\t\"price\": \"40000000元\"\n" +

"\t}],\n" +

"\t\"女朋友\": [{\n" +

"\t\t\"name\": \"爱丽丝\",\n" +

"\t\t\"age\": \"18\",\n" +

"\t\t\"height\": \"165cm\",\n" +

"\t\t\"weight\": \"95斤\",\n" +

"\t\t\"skill\": \"钢琴,舞蹈\"\n" +

"\t}, {\n" +

"\t\t\"name\": \"安妮\",\n" +

"\t\t\"age\": \"20\",\n" +

"\t\t\"height\": \"170cm\",\n" +

"\t\t\"weight\": \"100斤\",\n" +

"\t\t\"skill\": \"小提琴,唱歌,舞蹈\"\n" +

"\t}]\n" +

"}";

JSONObject jsonObject = JSON.parseObject(originalStr);

new JsonTest().travelLiJSONObject(jsonObject);

}

public void travelLiJSONObject(JSONObject originalJSONObject) {

for (String key : originalJSONObject.keySet()) { // 最外层的key

StringBuilder path = new StringBuilder(key);

Object value = originalJSONObject.get(key);

// 空字符串也是字符串

if (value instanceof String || value instanceof Number) {

System.out.println(key + " : " + value);

continue;

}

if (value instanceof JSONObject) {

JSONObject object = (JSONObject) value;

System.out.println("=======》" + key + "(json对象)");

travelLiJSONObject(object);

continue;

}

if (value instanceof JSONArray) {

System.out.println("=======》" + key + "(json数组)");

if (value == null) { //不会存在

System.out.println("***************************************8");

}

JSONArray jsonArray = (JSONArray) value;

if (jsonArray.isEmpty()) {

System.out.println(key + " : " + "[]");

continue;

} else {

for (int i = 0; i < jsonArray.size(); i++) {

JSONObject o1 = jsonArray.getJSONObject(i);

travelLiJSONObject(o1);

}

}

}

}

}

}

打印结果:

=======》房产(json数组) area : 220平米 address : 西虹市朱雀路888弄 price : 20000000元 area : 356平米 address : 西虹市龙门路666弄 price : 40000000元 =======》基本信息(json对象) weight : 150斤 age : 36 username : 王多鱼 height : 175cm hobby : 花钱 =======》女朋友(json数组) skill : 钢琴,舞蹈 name : 爱丽丝 weight : 95斤 age : 18 height : 165cm skill : 小提琴,唱歌,舞蹈 name : 安妮 weight : 100斤 age : 20 height : 170cm

实现起来也简单,用递归可以了。

好了,终于伺候好了王多鱼这个大老板角色。

欢迎大家留言讨论,一起交流,学习,进步!

保护原创,人人有责,抄袭可耻。

相关推荐

狗死后多久会臭-狗狗尸体多久会腐烂
365bet世界杯

狗死后多久会臭-狗狗尸体多久会腐烂

📅 06-28 ❤️ 392
氮化镓(GaN)在车载充电及DC/DC中的应用
365bet世界杯

氮化镓(GaN)在车载充电及DC/DC中的应用

📅 06-29 ❤️ 311
2022年太平洋台风季
365bet世界杯

2022年太平洋台风季

📅 06-28 ❤️ 851