java用递归处理父子关系的数据

本文介绍了如何使用Java的Stream流和递归方法处理具有父子关系的嵌套数据结构,如省、市、县,展示了如何构建TestBody实体类并运用示例代码展示结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

java用递归处理父子关系的数据
每天一个问题小记录,今天的问题如下
1.在我们开发过程中,系统业务中,常常会有这样的数据,就是有父子关系的结构,比如省,市,县,这就是一个嵌套结构,当要得到这些数据的时候,我们可以使用递归
下面是举例,先上实体类

package com.noodle.stream;

import lombok.AllArgsConstructor;
import lombok.Data;

import java.util.List;
@Data
@AllArgsConstructor
public class TestBody {
    private Long id;
    private Long pid;


    private List<TestBody> children;


}

因为主要是搞父子嵌套关系,所以我只写了两个字段,具体业务可以加具体字段,然后我们写测试类,如下:

package com.noodle.stream;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 树形结构
 * oracle 使用 start with connect by prior
 * mysql使用 普通sql 或 自定义函数
 * 核心都是:find_in_set 和 concat 函数
 */
public class TestTree {
    public static void main(String[] args) {
        List<TestBody> list = new ArrayList<>();
        TestBody body1 = new TestBody(100L,null,null);
        TestBody body2 = new TestBody(20L,100L,null);
        TestBody body3 = new TestBody(15L,100L,null);
        TestBody body4 = new TestBody(10L,20L,null);
        TestBody body5 = new TestBody(5L,10L,null);
        list.add(body1);
        list.add(body2);
        list.add(body3);
        list.add(body4);
        list.add(body5);


        List<TestBody> resourceTree =
                list.stream()
                        .filter(i -> i.getPid() == null)
                        .map(i -> {
                            i.setChildren(getChildren(i, list));
                            return i;
                        })
                        .collect(Collectors.toList());

        ObjectMapper objectMapper = new ObjectMapper();
        try {
            String json = objectMapper.writeValueAsString(resourceTree);
            System.out.println(json);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 递归获取子节点
     *
     * @param node 节点对象
     * @param list 列表对象
     * @return 树对象
     */
    private static List<TestBody> getChildren(TestBody node, List<TestBody> list) {
        return list.stream()
                //当 参数的节点 == 循环的父节点(说明参数的节点 找到儿子了)
                .filter(i -> node.getId().equals(i.getPid()))
                //再次递归设置调用
                .map(i -> {
                    i.setChildren(getChildren(i, list));
                    return i;
                })

                .collect(Collectors.toList());
    }


}

点击运行,我们看看结果

[
  {
    "id": 100,
    "pid": null,
    "children": [
      {
        "id": 20,
        "pid": 100,
        "children": [
          {
            "id": 10,
            "pid": 20,
            "children": [
              {
                "id": 5,
                "pid": 10,
                "children": [
                  
                ]
              }
            ]
          }
        ]
      },
      {
        "id": 15,
        "pid": 100,
        "children": [
          
        ]
      }
    ]
  }
]

可以看到,没啥问题,这里我们使用了递归和Java的stream流处理,减少了代码量,简洁多了。
如果使用oracle可以使用 start with connect by prior
最后,如果聪明可爱的你发现了本次分享的问题,不要懒惰哈,动动你的小手,评论区让我也学习一下哦
本次分享就这些,拜了个白

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值