Java将List<T>集合组装成树(Tree)树结构组装

把列表转换为树结构

/**
 * 把列表转换为树结构
 *
 * @param originalList 原始list数据
 * @param keyName 作为唯一标示的字段名称
 * @return 组装后的集合
 */
public static <T> List<T> getTree(List<T> originalList, String keyName) throws Exception {
    String parentFieldName = "parentId";
    String childrenFieldName = "children";

    // 获取根节点,即找出父节点为空的对象
    List<T> topList = new ArrayList<>();
    for (int i = 0; i < originalList.size(); i++) {
        T t = originalList.get(i);
        String parentId = BeanUtils.getProperty(t, parentFieldName);
        if (StringUtils.isBlank(parentId)) {
            topList.add(t);
        }
    }

    // 将根节点从原始list移除,减少下次处理数据
    originalList.removeAll(topList);

    // 递归封装树
    fillTree(topList, originalList, keyName, parentFieldName, childrenFieldName);

    return topList;
}

 

封装树

/**
 * 封装树
 *
 * @param parentList 要封装为树的父对象集合
 * @param originalList 原始list数据
 * @param keyName 作为唯一标示的字段名称
 * @param parentFieldName 模型中作为parent字段名称
 * @param childrenFieldName 模型中作为children的字段名称
 */
public static <T> void fillTree(List<T> parentList, List<T> originalList, String keyName, String parentFieldName, String childrenFieldName) throws Exception {
    for (int i = 0; i < parentList.size(); i++) {
        List<T> children = fillChildren(parentList.get(i), originalList, keyName, parentFieldName, childrenFieldName);
        if (children.isEmpty()) {
            continue;
        }
        originalList.removeAll(children);
        fillTree(children, originalList, keyName, parentFieldName, childrenFieldName);
    }
}

封装子对象

/**
 * 封装子对象
 *
 * @param parent 父对象
 * @param originalList 待处理对象集合
 * @param keyName 作为唯一标示的字段名称
 * @param parentFieldName 模型中作为parent字段名称
 * @param childrenFieldName 模型中作为children的字段名称
 */
public static <T> List<T> fillChildren(T parent, List<T> originalList, String keyName, String parentFieldName, String childrenFieldName) throws Exception {
    List<T> childList = new ArrayList<>();
    String parentId = BeanUtils.getProperty(parent, keyName);
    for (int i = 0; i < originalList.size(); i++) {
        T t = originalList.get(i);
        String childParentId = BeanUtils.getProperty(t, parentFieldName);
        if (parentId.equals(childParentId)) {
            childList.add(t);
        }
    }
    if (!childList.isEmpty()) {
        FieldUtils.writeDeclaredField(parent, childrenFieldName, childList, true);
    }
    return childList;
}

 

测试实体类

/**
 * 测试实体类
 */
public class Catalog {

    /**
     * 唯一编号 uuid
     */
    private String id;

    /**
     * 名称
     */
    private String name;

    /**
     * 父节点id
     */
    private String parentId;

    /**
     * 子节点(数据库中不存在该字段,仅用于传输数据使用)
     */
    private List<?> children;

    // 省略 get set
}

测试

/**
* 测试 一共有六个Catalog
* 其中:name1下面有三个子节点:name2、name3、name4
*      name2下面有两个子节点:name5、name6
*/
@Test
public void ListToMap() throws Exception {
    List<Catalog> list = new ArrayList<>();

    Catalog catalog = new Catalog();
    String flowId = randomUUID();
    catalog.setFlowId(flowId);
    catalog.setName("name1");
    list.add(catalog);

    catalog = new Catalog();
    String flowId2 = randomUUID();
    catalog.setFlowId(flowId2);
    catalog.setName("name2");
    catalog.setParentId(flowId);
    list.add(catalog);

    catalog = new Catalog();
    String flowId3 = randomUUID();
    catalog.setFlowId(flowId3);
    catalog.setName("name3");
    catalog.setParentId(flowId);
    list.add(catalog);

    catalog = new Catalog();
    String flowId4 = randomUUID();
    catalog.setFlowId(flowId4);
    catalog.setName("name4");
    catalog.setParentId(flowId);
    list.add(catalog);

    catalog = new Catalog();
    String flowId5 = randomUUID();
    catalog.setFlowId(flowId5);
    catalog.setName("name5");
    catalog.setParentId(flowId2);
    list.add(catalog);

    catalog = new Catalog();
    String flowId6 = randomUUID();
    catalog.setFlowId(flowId6);
    catalog.setName("name6");
    catalog.setParentId(flowId2);
    list.add(catalog);

    List<Catalog> tree = getTree(list, "flowId");
    System.out.println(JSON.toJSONString(tree));

    /* 装换后输出json样式
    [
      {
        "id" : "ee55dafee60d44a3a143bd3623f29aa9",
        "name" : "name1",
        "children" : [
          {
            "id" : "2e049bdb67624054ad989b511f1b7674",
            "parentId" : "ee55dafee60d44a3a143bd3623f29aa9",
            "name" : "name2",
            "children" : [
              {
                "id" : "9292a15c7a5e4983ac03d10c5fe12a14",
                "name" : "name5",
                "parentId" : "2e049bdb67624054ad989b511f1b7674"
              },
              {
                "id" : "6cd9608726a1438682f239b6017680ca",
                "name" : "name6",
                "parentId" : "2e049bdb67624054ad989b511f1b7674"
              }
            ]
          },
          {
            "id" : "98e90c9e23e445f980c4116bd4c83233",
            "name" : "name3",
            "parentId" : "ee55dafee60d44a3a143bd3623f29aa9"
          },
          {
            "id" : "5e67e73c6aef4eb19b63b4789dcc3486",
            "name" : "name4",
            "parentId" : "ee55dafee60d44a3a143bd3623f29aa9"
          }
        ]
      }
    ]
    */
}

protected String randomUUID() {
    return UUID.randomUUID().toString().replace("-", "");
}

转载于:https://www.cnblogs.com/wkaca7114/p/tree.html

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值