Java集合转成树的三种方法(listToTree)

说明:

  1. 以stream的方式进行转化

  2. 转成json处理再转成list

实体:

package com.utils;

import java.util.List;

/**
* @Description:
* @Author:
* @Date: 2021/12/16 9:35
*/
public class TestEntity {
private String name;
private String code;
private String parentCode;
private Integer age;
private List<TestEntity> children;

public List<TestEntity> getChildren() {
return children;
}

public void setChildren(List<TestEntity> children) {
this.children = children;
}

public String getName() {
return name;
}

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

public String getCode() {
return code;
}

public void setCode(String code) {
this.code = code;
}

public String getParentCode() {
return parentCode;
}

public void setParentCode(String parentCode) {
this.parentCode = parentCode;
}

public Integer getAge() {
return age;
}

public void setAge(Integer age) {
this.age = age;
}

@Override
public String toString() {
return "TestEntity{" +
"name='" + name + '\'' +
", code='" + code + '\'' +
", parentCode='" + parentCode + '\'' +
", age=" + age +
", children=" + children +
'}';
}
}

 

方法一:

public static void main(String[] args) {
List<TestEntity> list1 = new ArrayList<>();
   TestEntity testEntity = new TestEntity();
   testEntity.setName("张三");
   testEntity.setCode("45612");
   testEntity.setParentCode("");
   testEntity.setAge(0);
   TestEntity testEntity1 = new TestEntity();
   testEntity1.setName("李四");
   testEntity1.setCode("342");
   testEntity1.setParentCode("45612");
   testEntity1.setAge(0);
   TestEntity testEntity2 = new TestEntity();
   testEntity2.setName("王五");
   testEntity2.setCode("435342");
   testEntity2.setParentCode("342");
   testEntity2.setAge(0);
   TestEntity testEntity3 = new TestEntity();
   testEntity3.setName("王6");
   testEntity3.setCode("11");
   testEntity3.setParentCode("");
   testEntity3.setAge(0);
   list1.add(testEntity);
   list1.add(testEntity1);
   list1.add(testEntity2);
   list1.add(testEntity3);
   
   //要点
   Map<String, List<TestEntity>> parentMap = list1.stream().collect(Collectors.groupingBy(TestEntity::getParentCode));
   list1.forEach(item -> { item.setChildren(parentMap.get(item.getCode())); });
   //过滤出根节点集合,根节点已经包含了孩子节点
   String root = "";
   List<TestEntity> testEntities = list1.stream().filter(item -> root.equals(item.getParentCode())).collect(Collectors.toList());

方法二:

这个需要引入json包

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.74</version>
</dependency>
    /**
* @param testEntities :要转成树的集合
* @param keyMark       :集合中实体父子关系字段的名称
* @param parentKeyMark :集合中实体父子关系字段的名称
* @param childMark     :集合中实体孩子集合字段的名称
* @return List:树集合
* @Date : 2021/12/16 15:07
* @description :testEntities、testEntities、testEntities三个就是字段字符串,如TestEntity中有字段String id,String parentId,String name,List<TestEntity> child字段,方法的
* keyMark、parentKeyMark、childMark就是“id”、"parentId"、"child"
*/
public static List<TestEntity> listToTree(List<TestEntity> testEntities, String keyMark, String parentKeyMark, String childMark) {
JSONArray jsonArray = JSONArray.parseArray(JSONObject.toJSONString(testEntities));
JSONArray jsonArrayTree = new JSONArray();
JSONObject hash = new JSONObject();
//将数组转为Object的形式,key为数组中的id
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject json = (JSONObject) jsonArray.get(i);
hash.put(json.getString(keyMark), json);
}
//遍历结果集
for (int j = 0; j < jsonArray.size(); j++) {
//单条记录
JSONObject aVal = (JSONObject) jsonArray.get(j);
//在hash中取出key为单条记录中pid的值
if (null != aVal.get(parentKeyMark) && !"".equals(aVal.get(parentKeyMark))) {
JSONObject hashVP = (JSONObject) hash.get(aVal.get(parentKeyMark).toString());
//如果记录的pid存在,则说明它有父节点,将她添加到孩子节点的集合中
if (hashVP != null) {
//检查是否有child属性
if (hashVP.get(childMark) != null) {
JSONArray ch = (JSONArray) hashVP.get(childMark);
ch.add(aVal);
hashVP.put(childMark, ch);
} else {
JSONArray ch = new JSONArray();
ch.add(aVal);
hashVP.put(childMark, ch);
}
} else {
jsonArrayTree.add(aVal);
}
} else {
jsonArrayTree.add(aVal);
}

}
return jsonArrayTree.toJavaList(TestEntity.class);
}

 

方法三:

/**
* 使用递归方法建树
* @param testEntity 子节点集合
* @return List<TestEntity>
*/
public static List<TestEntity> buildTree(List<TestEntity> testEntity) {
List<TestEntity> trees = new ArrayList<>();
for (TestEntity TestEntity : testEntity) {
String parentCode = TestEntity.getParentCode();
if (null == parentCode || "-".equals(parentCode)) {
trees.add(findChildren(TestEntity, testEntity));
}
}
return trees;
}

/**
* 递归查找子节点
* @param TestEntity 菜单数对象
* @param testEntity 子节点
* @return MenuTree
*/
private static TestEntity findChildren(TestEntity TestEntity, List<TestEntity> testEntity) {
for (TestEntity it : testEntity) {
if (TestEntity.getCode().equals(it.getParentCode())) {
if (TestEntity.getChildren() == null) {
TestEntity.setChildren(new ArrayList<TestEntity>());
}
TestEntity.getChildren().add(findChildren(it, testEntity));
}
}
return TestEntity;
}
posted @   入世则饮江湖浊酒一杯  阅读(3192)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
点击右上角即可分享
微信分享提示