Java递归遍历多叉树结构JSON

17 篇文章 0 订阅
15 篇文章 0 订阅

Java递归遍历获取一个节点的所有父节点id

前言:

这个是一个多叉树,节点数量没有规律,适用于每个节点只有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;
        }
    }
}


/** * 根据等级查询类目树 * * @param level * @return */ @Override public List queryCategoryTree(Integer level) { //查询当前级别下类目 List list = categoryDAO.list(level); //组装好的类目树,返回前端 List categoryTree = new ArrayList(); //所有类目 List allDTOList = new ArrayList(); if (CollectionUtils.isEmpty(list)) { return categoryTree; } for (CategoryDO categoryDO : list) { allDTOList.add(new CategoryTreeDTO().convertDOToDTO(categoryDO)); } //当前等级类目 categoryTree = allDTOList.stream().filter(dto -> level.equals(dto.getLevel())).collect(Collectors.toList()); for (CategoryTreeDTO categoryTreeDTO : categoryTree) { //组装类目为树结构 assembleTree(categoryTreeDTO, allDTOList,Constants.CATEGORY_MAX_LEVEL - level); } return categoryTree; } /** * 组装树 * * @param categoryTreeDTO * @param allList * @param remainRecursionCount 剩余递归次数 * @return */ public CategoryTreeDTO assembleTree(CategoryTreeDTO categoryTreeDTO, List allList, int remainRecursionCount) { remainRecursionCount--; //最大递归次数不超过Constants.CATEGORY_MAX_LEVEL-level次,防止坏数据死循环 if(remainRecursionCount < 0){ return categoryTreeDTO; } String categoryCode = categoryTreeDTO.getCategoryCode(); Integer level = categoryTreeDTO.getLevel(); //到达最后等级树返回 if (Constants.CATEGORY_MAX_LEVEL == level) { return categoryTreeDTO; } //子类目 List child = allList.stream().filter(a -> categoryCode.equals(a.getParentCode())).collect(Collectors.toList()); if (null == child) { return categoryTreeDTO; } categoryTreeDTO.setChildren(child); //组装子类目 for (CategoryTreeDTO dto : child) { assembleTree(dto, allList,remainRecursionCount); } return categoryTreeDTO; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值