Java把List集合转成树形结构
1. 实体类
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.22</version>
</dependency>
package com.utils;
import lombok.Data;
import java.util.List;
/**
* @Description:
* @Author:
* @Date: 2021/12/16 9:35
*/
@Data
public class TestEntity {
private int id;
private String name;
private int parentId;
private List<TestEntity> children;
}
2. 方法一:使用Stream流
private static List<TestEntity> listToTree1(List<TestEntity> list) {
// 要点
// 通过Collectors.groupingBy(Address::getPid)方法对addresses按照Pid进行分组,也就是将pid相同的放在一起
Map<Integer, List<TestEntity>> parentMap = list.stream().collect(Collectors.groupingBy(TestEntity::getParentId));
list.forEach(item -> {
item.setChildren(parentMap.get(item.getId()));
});
// 过滤出根节点集合,根节点已经包含了孩子节点
List<TestEntity> newList = list.stream().filter(item -> item.getParentId() == 0).collect(Collectors.toList());
return newList;
}
3. 方法二:使用fastjson
添加依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.73</version>
</dependency>
/**
* @param list :要转成树的集合
* @param keyMark :id
* @param parentKeyMark :pid
* @param childMark :children
* @return List:树集合
* @description :如TestEntity中有字段 int id,String name,int parentId,List<TestEntity> children字段
* keyMark、parentKeyMark、childMark就是 "id", "parentId", "children"
*/
public static List<TestEntity> listToTree2(List<TestEntity> list, String keyMark, String parentKeyMark, String childMark) {
JSONArray jsonArray = JSONArray.parseArray(JSONObject.toJSONString(list));
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);
}
4. 方法三:使用递归
/**
* 使用递归方法建树
*
* @param list 要转成树的集合
* @return List
*/
public static List<TestEntity> listToTree2(List<TestEntity> list) {
List<TestEntity> trees = new ArrayList<>();
for (TestEntity entity : list) {
int parentId = entity.getParentId();
if (parentId == 0) {
// 是父级
trees.add(findChildren(entity, list));
}
}
return trees;
}
/**
* 递归查找子节点
*
* @param entity 对象
* @param list 子节点
* @return MenuTree
*/
private static TestEntity findChildren(TestEntity entity, List<TestEntity> list) {
for (TestEntity info : list) {
if (entity.getId() == info.getParentId()) {
if (entity.getChildren() == null) {
entity.setChildren(new ArrayList<>());
}
entity.getChildren().add(findChildren(info, list));
}
}
return entity;
}
5. 完整测试类
package list;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class ListToTreeTest {
public static void main(String[] args) {
List<TestEntity> list = new ArrayList<>();
TestEntity testEntity1 = new TestEntity();
testEntity1.setId(1);
testEntity1.setName("张三");
testEntity1.setParentId(0);
TestEntity testEntity2 = new TestEntity();
testEntity2.setId(2);
testEntity2.setName("李四");
testEntity2.setParentId(0);
TestEntity testEntity3 = new TestEntity();
testEntity3.setId(3);
testEntity3.setName("张三儿子");
testEntity3.setParentId(1);
list.add(testEntity1);
list.add(testEntity2);
list.add(testEntity3);
List<TestEntity> result1 = listToTree1(list);
System.out.println(result1);
// List<TestEntity> result2 = listToTree2(list, "id", "parentId", "children");
// System.out.println(result2);
// List<TestEntity> result3 = listToTree3(list);
// System.out.println(result3);
}
private static List<TestEntity> listToTree1(List<TestEntity> list) {
// 要点
// 通过Collectors.groupingBy(Address::getPid)方法对addresses按照Pid进行分组,也就是将pid相同的放在一起
Map<Integer, List<TestEntity>> parentMap = list.stream().collect(Collectors.groupingBy(TestEntity::getParentId));
list.forEach(item -> {
item.setChildren(parentMap.get(item.getId()));
});
// 过滤出根节点集合,根节点已经包含了孩子节点
List<TestEntity> newList = list.stream().filter(item -> item.getParentId() == 0).collect(Collectors.toList());
return newList;
}
/**
* @param list :要转成树的集合
* @param keyMark :id
* @param parentKeyMark :pid
* @param childMark :children
* @return List:树集合
* @description :如TestEntity中有字段 int id,String name,int parentId,List<TestEntity> children字段
* keyMark、parentKeyMark、childMark就是 "id", "parentId", "children"
*/
public static List<TestEntity> listToTree2(List<TestEntity> list, String keyMark, String parentKeyMark, String childMark) {
JSONArray jsonArray = JSONArray.parseArray(JSONObject.toJSONString(list));
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 list 要转成树的集合
* @return List
*/
public static List<TestEntity> listToTree3(List<TestEntity> list) {
List<TestEntity> trees = new ArrayList<>();
for (TestEntity entity : list) {
int parentId = entity.getParentId();
if (parentId == 0) {
// 是父级
trees.add(findChildren(entity, list));
}
}
return trees;
}
/**
* 递归查找子节点
*
* @param entity 对象
* @param list 子节点
* @return MenuTree
*/
private static TestEntity findChildren(TestEntity entity, List<TestEntity> list) {
for (TestEntity info : list) {
if (entity.getId() == info.getParentId()) {
if (entity.getChildren() == null) {
entity.setChildren(new ArrayList<>());
}
entity.getChildren().add(findChildren(info, list));
}
}
return entity;
}
}