遍历JSONObject、JSONArray (适用任意复杂结构类型)
本文讲述如何遍历简单JSONObject,嵌套JSONObject,任意类型JSONObject的遍历操作。
多数时候,我们可能只需要获取JSONObject里的某个键值对,但有时候,我们需要遍历整个JSONObject对象。
本文用的是alibaba的fastjson,如果没有用过fastjson,可以在pom.xml里添加下面的依赖。
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.24</version>
</dependency>
先说简单的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<String, Object> 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<String, Object>, Cloneable, Serializable, InvocationHandler
看到没,JSONObject是一个实现了Map<String, Object>的类。
我们再看,JSONObject里面有这样一个属性: private final Map<String, Object> 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<String, Object> entry : baseInfo.entrySet()) {
System.out.println(entry.getKey() + " : " + entry.getValue());
}
System.out.println();
// 遍历房产信息
for (Map.Entry<String, Object> 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<String, Object> 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<String, Object> 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
实现起来也简单,用递归可以了。
好了,终于伺候好了王多鱼这个大老板角色。
欢迎大家留言讨论,一起交流,学习,进步!
保护原创,人人有责,抄袭可耻。
更多推荐
所有评论(0)