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

2023-05-16

多数时候,我们可能只需要获取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

   实现起来也简单,用递归可以了。好了,终于伺候好了王多鱼这个大老板角色。
 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

遍历JSONObject、JSONArray (适用任意复杂结构类型) 的相关文章

随机推荐