java 递归获取树形结构化数据(不需要多次查询数据库)

我们在开发中会经常用到树形结构化数据,有很多同学的处理方式是根据父级id递归查询数据库。这样的方式是不太可取的,最好的方式是在代码层级控制。代码样例如下:

package com.ican.kqyz.system.utils;

import com.alibaba.fastjson.JSON;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * @Description: 子集处理类
 * @Title: ChildHandle
 * @Package com.ican.kqyz.system.utils
 * @Author: zangdy
 * @CreateTime: 2022/10/20 10:06
 */
public class ChildHandle {
    /** id */
    private Integer id;
    /** 父级id */
    private Integer parentId;
    /** 名称 */
    private String name;
    /** 子集 */
    private List<ChildHandle> child;

    public static void main(String[] args) {
        // 模拟数据
        List<ChildHandle> list = mockData();
        // 获取层级关系
        list = getChild(0, list);
        System.out.println(JSON.toJSONString(list));
    }
    
    /**
     * 获取子集
     *
     * @param parentId
     * @param list
     * @return
     */
    public static List<ChildHandle> getChild(Integer parentId, List<ChildHandle> list) {
        if (CollectionUtils.isEmpty(list) || parentId == null) {
            return null;
        }
        // 组装新的树形结构数据
        List<ChildHandle> newList = new ArrayList<>();
        for (ChildHandle child : list) {
            // 如果父级内码是当前内码,就继续
            if (parentId.equals(child.getParentId())) {
                // 寻找下级
                child.setChild(getChild(child.getId(), list));
                newList.add(child);
            }
        }
        return newList;
    }

    /**
     * 模拟数据
     * @return
     */
    private static List<ChildHandle> mockData() {
        List<ChildHandle> list = new ArrayList<>();
        ChildHandle ch1 = new ChildHandle();
        ch1.setId(1);
        ch1.setParentId(0);
        ch1.setName("测试000");
        list.add(ch1);

        ChildHandle ch2 = new ChildHandle();
        ch2.setId(2);
        ch2.setParentId(0);
        ch2.setName("测试011");
        list.add(ch2);

        ChildHandle ch3 = new ChildHandle();
        ch3.setId(3);
        ch3.setParentId(2);
        ch3.setName("测试333");
        list.add(ch3);

        ChildHandle ch4 = new ChildHandle();
        ch4.setId(4);
        ch4.setParentId(1);
        ch4.setName("测试020");
        list.add(ch4);

        ChildHandle ch5 = new ChildHandle();
        ch5.setId(5);
        ch5.setParentId(1);
        ch5.setName("测试030");
        list.add(ch5);

        ChildHandle ch6 = new ChildHandle();
        ch6.setId(6);
        ch6.setParentId(4);
        ch6.setName("测试20");
        list.add(ch6);

        ChildHandle ch7 = new ChildHandle();
        ch7.setId(7);
        ch7.setParentId(6);
        ch7.setName("测试203");
        list.add(ch7);
        return list;
    }

    public Integer getParentId() {
        return parentId;
    }

    public void setParentId(Integer parentId) {
        this.parentId = parentId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<ChildHandle> getChild() {
        return child;
    }

    public void setChild(List<ChildHandle> child) {
        this.child = child;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }
}

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
/** * 根据等级查询类目树 * * @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、付费专栏及课程。

余额充值