前言:
这个是一个多叉树,节点数量没有规律,适用于每个节点只有child属性没有parent属性的、每个节点有不同数量子节点的树,本人算法非常弱,希望有大佬可以有更高效的方法告诉我。
场景:
在服务器里有一个test.json文件,要将这个文件解析,获取其中一个节点的所有父节点ID。
json文件内容:
{
"CHILD": [
{
"CHILD": [
{
"CHILD": [
],
"OBJ_ID": "22031700000011"
},
{
"CHILD": [
{
"CHILD": [
],
"OBJ_ID": "22031700000013"
}
],
"OBJ_ID": "22031700000012"
}
],
"OBJ_ID": "22022300001151"
},
{
"CHILD": [
{
"CHILD": [
{
"CHILD": [
],
"OBJ_ID": "22031700000017"
},
{
"CHILD": [
{
"CHILD": [
],
"OBJ_ID": "22031700000015"
}
],
"OBJ_ID": "22031700000016"
}
],
"OBJ_ID": "22031700000014"
}
],
"OBJ_ID": "22022300001150"
}
],
"ZUXIAN_NAME": "祖先",
"ZUXIAN_ID": "22022300000013"
}
思路:
由于json节点里面只有child[]这个关联关系,每一个节点都没有parentid的概念,所以需要用两遍递归,我第一遍递归,把这个json里的每一个节点的ID和其childID都理出来放在一个ArrayList里了,大概是这种格式"pid;childid@childid@childid",然后再递归这个ArrayList,比如传入的id是x,就看List里pid;childid@childid@childid的childid有没有包含这个x,如果包含,则拼接pid+","到结果里,然后把pid作为参数再进行递归,递归完一遍就得到了所有的pid
源码:
/**
* @description:
* @author: niuwenda
* @date: 2022年7月12日上午11:25:06
* @modify:
*/
package com.topscomm.dist.util;
import sun.misc.BASE64Decoder;
import javax.imageio.ImageIO;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.UncheckedIOException;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
import java.util.List;
public class Test{
public static void main(String[] args) throws Exception{
String startId = "22031700000015";
String jsonPath = "D:\\temp\\ftpTemp\\test.json";
String jg = analysisJson(startId,jsonPath);
System.out.println(jg);
}
public static String analysisJson(String startId,String jsonPath){
File jsonFile = new File(jsonPath);
//通过上面那个方法获取json文件的内容
String jsonData = getJsonStr(jsonFile);
//转json对象
JSONObject jsonObj = (JSONObject)JSONObject.parse(jsonData);
//获取主要数据
ArrayList<String> fAreaList = new ArrayList();
StringBuffer res = new StringBuffer();
recursionJson(jsonObj,fAreaList);
recursionArray(fAreaList,startId,res);
System.out.println("结束");
String str = res.toString();
return str;
}
//static String res="";
public static void recursionJson(JSONObject jsonObj,ArrayList<String> fAreaList){
//当前节点所有的子节点
JSONArray childArr = jsonObj.getJSONArray("CHILD");
//盛放该节点的id和子节点的id
String childIds="";
//如果当前节点没有子节点,只记录当前节点id
if(childArr.size()==0){
//fAreaList.add(jsonObj.get("OBJ_ID")+"");
return;
}
//拼接父子节点id,父子节点id用分号分开,子节点用逗号分开
for(int i=0;i<childArr.size();i++){
JSONObject childObj = (JSONObject)childArr.get(i);
childIds+=childObj.get("OBJ_ID")+"@";
}
fAreaList.add(jsonObj.get("OBJ_ID")+";"+childIds);
//递归继续遍历
for(int i=0;i<childArr.size();i++){
JSONObject childObj = (JSONObject)childArr.get(i);
recursionJson(childObj,fAreaList);
}
}
public static void recursionArray(ArrayList<String> fAreaList,String childId,StringBuffer ress){
if(childId.contains("null")){
return;
}
int sign=0;
for(int i=0;i<fAreaList.size();i++){
String[] childAndParent = fAreaList.get(i).split(";");
String[] childIds = childAndParent[1].split("@");
String pid = childAndParent[0];
for(String s:childIds){
if(childId.equals(s)){
//拼接子节点,父节点
if(!"null".equals(pid)){
//res+=pid+",";
ress.append(pid+",");
}
sign++;
//继续递归查此节点的父节点又是谁的子节点
recursionArray(fAreaList,pid,ress);
}
}
}
if(sign==0){
return;
}
}
//把一个文件中的内容读取成一个String字符串
public static String getJsonStr(File jsonFile){
String jsonStr = "";
try {
FileReader fileReader = new FileReader(jsonFile);
Reader reader = new InputStreamReader(new FileInputStream(jsonFile),"utf-8");
int ch = 0;
StringBuffer sb = new StringBuffer();
while ((ch = reader.read()) != -1) {
sb.append((char) ch);
}
fileReader.close();
reader.close();
jsonStr = sb.toString();
return jsonStr;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
}