Java List与树的互转
平时工作中都会遇到包含层级关系的List数据转换成树形结构,或者数据已是树形结构了,需要我们处理成普通的单层list结构。以下代码均为本人实际开发所写代码,可能不是最优解、复杂度也比较高,在此和大家一起分享学习!
注:该工具类支持将list转换成树/森林。可自行测试,有疑问或更优方案,可私聊我。
TreeNode
@Data @JsonInclude(JsonInclude.Include.NON_NULL) public class TreeNode<T> { private String id; private String key; private String value;
private String name; private String parentId; private String createName; private LocalDateTime createTime; private List<TreeNode<T>> children; private boolean hasParent = false; private boolean hasChildren = false; public void initChildren() { this.children = new ArrayList<>(); } }
TreeUtil
public class TreeUtil { protected TreeUtil() { } private final static String TOP_NODE_ID = "0"; /** * 使用递归方法建树 * * @param nodes * @return */ public static List<TreeNode<T>> buildByRecursive(List<TreeNode<T>> nodes) { List<TreeNode<T>> trees = new ArrayList<>(); for (TreeNode<T> treeNode : nodes) { if (TOP_NODE_ID.equals(treeNode.getParentId())) { trees.add(findChildren(treeNode,nodes)); } } return trees; } /** * 递归查找子节点 * * @param treeNodes * @return */ public static TreeNode<T> findChildren(TreeNode<T> treeNode, List<TreeNode<T>> treeNodes) { for (TreeNode<T> it : treeNodes) { if (treeNode.getId().equals(it.getParentId())) { if (treeNode.getChildren() == null) { treeNode.setChildren(new ArrayList<TreeNode<T>>()); } treeNode.getChildren().add(findChildren(it, treeNodes)); } } return treeNode; } public static void buildTrees(List<TreeNode<T>> trees, List<T> list) { list.forEach(entity -> { TreeNode<T> tree = new TreeNode<>(); tree.setId(entity.getId()); tree.setKey(entity.getId()); tree.setValue(entity.getId()); tree.setName(entity.getName()); tree.setParentId(entity.getParentId()); tree.setCreateTime(entity.getCreateTime()); tree.setCreateName(entity.getCreateName()); trees.add(tree); }); } public static <T> List<TreeNode<T>> buildTreeList(List<TreeNode<T>> nodes) { if (nodes == null) { return null; } List<TreeNode<T>> topNodes = new ArrayList<>(); //利用两层循环,组装树/森林结构 nodes.forEach(first -> { String pid = first.getParentId(); first.setHasParent(true); if (pid == null || TOP_NODE_ID.equals(pid)) { topNodes.add(first); first.setHasParent(false); } else { boolean isExistPid = false; for (TreeNode<T> temp : nodes) { if (temp.getId().equals(pid)) { isExistPid = true; } } if (!isExistPid) { topNodes.add(first); first.setHasParent(false); } } for (TreeNode<T> second : nodes) { String id = second.getId(); if (id != null && id.equals(pid)) { if (second.getChildren() == null) { second.initChildren(); } second.getChildren().add(first); first.setHasParent(true); second.setHasChildren(true); second.setHasParent(true); return; } } }); return topNodes; } public static <T> TreeNode<T> buildTree(List<TreeNode<T>> nodes) { if (nodes == null) { return null; } List<TreeNode<T>> topNodes = new ArrayList<>(); //利用两层循环,组装树/森林结构 nodes.forEach(first -> { String pid = first.getParentId(); first.setHasParent(true); if (pid == null || TOP_NODE_ID.equals(pid)) { topNodes.add(first); first.setHasParent(false); } else { boolean isExistPid = false; for (TreeNode<T> temp : nodes) { if (temp.getId().equals(pid)) { isExistPid = true; } } if (!isExistPid) { topNodes.add(first); first.setHasParent(false); } } for (TreeNode<T> second : nodes) { String id = second.getId(); if (id != null && id.equals(pid)) { if (second.getChildren() == null) { second.initChildren(); } second.getChildren().add(first); first.setHasParent(true); second.setHasChildren(true); second.setHasParent(true); return; } } }); TreeNode<T> root = new TreeNode<>(); root.setId("0"); root.setParentId(""); root.setHasParent(false); root.setHasChildren(true); root.setChildren(topNodes); root.setName("root"); return root; } public static <T> List<TreeNode<T>> tree2List(List<TreeNode<T>> treeList) { List<TreeNode<T>> list = new ArrayList<>(); for (TreeNode<T> tree : treeList) { List<TreeNode<T>> child = tree.getChildren(); list.add(tree); if (child != null && child.size() > 0) { list.addAll(tree2List(child)); tree.setChildren(null); } } return list; } }
作者:JackpotHan
欢迎任何形式的转载,但请务必注明出处。
限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix