listmap
承灿 2023/4/7
# 1 对象List转为Tree树形结构
public final List<Map<String, Object>> listToTree(List<Map<String, Object>> entityList, String primaryFieldName, String parentFieldName) {
//返回的map Tree树形结构
List<Map<String, Object>> treeMap = new ArrayList<>();
//将传进的参数entityList转为MapList
List<Map<String, Object>> listMap = JSON.parseObject(JSON.toJSONString(entityList), List.class);
//声明一个map用来存listMap中的对象,key为对象id,value为对象本身
Map<String, Map<String, Object>> entityMap = new Hashtable<>();
//循环listMap把map对象put到entityMap中去
listMap.forEach(map -> entityMap.put(map.get(primaryFieldName).toString(), map));
//循环listMap进行Tree树形结构组装
listMap.forEach(map -> {
//获取map的pid
Object pid = map.get(parentFieldName);
//判断pid是否为空或者为0,为空说明是最顶级,直接add到返回的treeMap中去
if (pid == null || StringUtils.equals(pid.toString(), String.valueOf(1))) {
treeMap.add(map);
} else {
//如果pid不为空也不为0,是子集
// 根据当前map的pid获取上级 parentMap
Map<String, Object> parentMap = entityMap.get(pid.toString());
if (parentMap == null) { //如果parentMap为空,则说明当前map没有父级,当前map就是顶级
treeMap.add(map);
} else {
//如果parentMap不为空,则当前map为parentMap的子级
//取出parentMap的所有子级的List集合
List<Map<String, Object>> children = (List<Map<String, Object>>) parentMap.get(CHILDREN);
if (children == null) { //判断子级集合是否为空,为空则新创建List
children = new ArrayList<>();
parentMap.put(CHILDREN, children);
}
//把当前map对象add到parentMap的子级List中去
children.add(map);
/**
* 因为parentMap是从entityMap中get出来的,
* 而entityMap中的value又是来自于listMap对象,
* 所以parentMap和entityMap中的value的地址都是指向listMap中的对象,
* 所以parentMap的children和entityMap中的value的children改变时,都会改变listMap中的对象,
*/
}
}
});
return treeMap;
}
# 2 List
List<Map<String, Object>> param //这是一个有children子节点的集合,每一个节点都是一个map
//创建一个新的list map
List<Map<String, Object>> newList = new ArrayList<>();
//遍历param里面的每一个map
for (Map<String, Object> map : param) {
//创建一个新的map来存储数据
Map<String, Object> newMap = new HashMap<>();
//把map里面的键值对复制到新的map中
newMap.putAll(map);
//判断是否有children这个键
if (newMap.containsKey("children")) {
//获取children对应的值(一个List<Map<String, Object>>)
try {
List<Map<String, Object>> children = (List<Map<String, Object>>) newMap.get("children");
//遍历children里面的每一个子map
for (Map<String, Object> child : children) {
//创建一个新的子map来存储数据
Map<String, Object> newChild = new HashMap<>();
//把子map里面的键值对复制到新的子map中
newChild.putAll(child);
//把新的子map添加到新的list中
newList.add(newChild);
}
//从新的map中移除children这个键,因为它已经被处理过了
newMap.remove("children");
} catch (ClassCastException e) {
log.error(e.getMessage());
//抛出新的自定义异常
throw new MyException(e.getMessage() + "输入类型格式错误");
}
}
//把新的map添加到新的list中
newList.add(newMap);
}
# 3 buildTree v1 v2版本
package com.example.community.stream;
import com.example.community.model.entity.Tree;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @author: lichengcan
* @date: 2023-07-28 17:00
* @description buildTree
**/
public class TreeStreamTest {
public static List<Tree> createTreeList() {
List<Tree> TreeList = new ArrayList<>();
TreeList.add(new Tree("f", "e", "fff"));
TreeList.add(new Tree("a", "0", "lcc"));
TreeList.add(new Tree("b", "0", "bbb"));
TreeList.add(new Tree("c", "0", "ccc"));
TreeList.add(new Tree("h", "g", "hhhhh"));
TreeList.add(new Tree("d", "a", "ddd"));
TreeList.add(new Tree("e", "b", "eee"));
TreeList.add(new Tree("g", "e", "fff"));
TreeList.add(new Tree("i", "x", "iiii"));
return TreeList;
}
public static void main(String[] args) {
//初始化数据
List<Tree> treeList = createTreeList();
//获取根节点
List<Tree> trees = getRoot(treeList);
System.out.println("trees = " + trees);
//构建树v2版本
buildTreeV2(treeList);
}
public static List<Tree> getRoot(List<Tree> trees) {
List<Tree> roots = trees.stream().filter(x -> x.getParentId().equals("0")).collect(Collectors.toList());
//构建树形结构
roots.stream().forEach(root -> buildTreeV1(root, trees));
//只保留根节点对象
return trees.stream().filter(tree -> tree.getParentId().equals("0")).collect(Collectors.toList());
}
public static void buildTreeV1(Tree root, List<Tree> trees) {
trees.stream()
.forEach(tree -> {
if (tree.getParentId().equals(root.getId())) {
if (root.getChild() == null) {
root.setChild(new ArrayList<>());
}
root.getChild().add(tree);
//把当前节点和整个数组重新
buildTreeV1(tree, trees);
}
});
}
public static List<Tree> buildTreeV2(List<Tree> trees) {
//将List转换成map,id作为key可以更方便的拿到父节点、子节点,减少了重复扫描整个列表,降低了时间复杂度
Map<String, Tree> treeMap = trees.stream().collect(Collectors.toMap(Tree::getId, t -> t));
//开始构建树
List<Tree> roots = new ArrayList<>();
trees.stream().forEach(tree -> {
//当前节点的爸爸id
String parentId = tree.getParentId();
//是不是老大
if ("0".equals(parentId)) {
roots.add(tree);
} else {
//不是老大
//拿到爸爸
Tree parent = treeMap.get(parentId);
//爸爸没有儿子
if (parent != null) {
//初始化空儿子
if (parent.getChild() == null) {
parent.setChild(new ArrayList<>());
}
//给他一个亲生儿子
parent.getChild().add(tree);
}
}
});
return roots;
}
}