java无限递归遍历json对象问题

 更新时间:2023年07月24日 11:25:54   作者:赶路人儿  
这篇文章主要介绍了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 




[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}]

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • File.createTempFile创建临时文件的示例详解

    File.createTempFile创建临时文件的示例详解

    这篇文章主要介绍了File.createTempFile创建临时文件的示例详解,在默认临时文件目录中创建一个空文件,使用给定前缀和后缀生成其名称。 如果感兴趣来了解一下
    2020-07-07
  • 解析分别用递归与循环的方式求斐波那契数列的实现方法

    解析分别用递归与循环的方式求斐波那契数列的实现方法

    本篇文章是对分别用递归与循环的方式求斐波那契数列的方法进行了详细的分析介绍,需要的朋友参考下
    2013-06-06
  • mybatis框架入门学习教程

    mybatis框架入门学习教程

    MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架。这篇文章主要介绍了mybatis框架入门学习教程,需要的朋友可以参考下
    2017-02-02
  • Java面向对象之作用域详细解读

    Java面向对象之作用域详细解读

    这篇文章主要介绍了Java面向对象之作用域详细解读,在java编程中,主要的变量就是属性和局部变量,局部变量一般是指在成员方法中定义的变量,局部变量也就是除了属性之外的其他变量,作用域为定义他的代码块中,需要的朋友可以参考下
    2024-01-01
  • 一篇文章带你入门Java运算符

    一篇文章带你入门Java运算符

    这篇文章主要介绍了Java基本数据类型和运算符,结合实例形式详细分析了java基本数据类型、数据类型转换、算术运算符、逻辑运算符等相关原理与操作技巧,需要的朋友可以参考下
    2021-08-08
  • java制作仿微信录制小视频控件

    java制作仿微信录制小视频控件

    这篇文章主要介绍了java制作仿微信录制小视频控件的代码,录制小视频非常方便,有需要的小伙伴可以参考下。
    2015-04-04
  • 解决JDK8的ParallelStream遍历无序的问题

    解决JDK8的ParallelStream遍历无序的问题

    这篇文章主要介绍了解决JDK8的ParallelStream遍历无序的问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-07-07
  • Springboot实现根据条件切换注入不同实现类的示例代码

    Springboot实现根据条件切换注入不同实现类的示例代码

    这篇文章主要介绍了Springboot实现根据条件切换注入不同实现类的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • Java中Dom4j的配置与使用示例详解

    Java中Dom4j的配置与使用示例详解

    Dom4j是一个强大的Java库,用于处理XML数据,结合了DOM、SAX、JDOM的优点,它可以解析、生成、修改和序列化XML文档,适用于数据交换、配置文件管理、日志记录、数据持久化和Web服务等场景,Dom4j提供了简单易用的API,便于开发者进行高效的XML操作
    2024-10-10
  • macOS下Spring Boot开发环境搭建教程

    macOS下Spring Boot开发环境搭建教程

    这篇文章主要为大家详细介绍了macOS下Spring Boot开发环境搭建教程,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01

最新评论