java构建树(tree)型结构,只循环一次非递归
只循环一次构建树形结构,可以直接加入工具类使用,代码如下
public static <T, I> List<T> lambdaGenerateTree(List<T> allTreeNode, Callback<T, I> getIdCallback, Callback<T, I> getParentIdCallback, BiConsumer<T, List<T>> setChildrenListCallback, I topParentId) { List<T> topTreeNodeList = new ArrayList<>(); Map<I, List<T>> allTreeNodeChildrenMap = new HashMap<>(allTreeNode.size()); allTreeNode.forEach(treeNode -> { if (allTreeNodeChildrenMap.containsKey(getIdCallback.call(treeNode))) { // 该节点children已始化时建立引用 setChildrenListCallback.accept(treeNode, allTreeNodeChildrenMap.get(getIdCallback.call(treeNode))); } else { // 该节点children还未初始化时进行初始化并建立引用 List<T> childrenList = new ArrayList<>(); setChildrenListCallback.accept(treeNode, childrenList); allTreeNodeChildrenMap.put(getIdCallback.call(treeNode), childrenList); } if (getParentIdCallback == topParentId || getParentIdCallback.call(treeNode).equals(topParentId)) { // top节点将节点放入top节点的List中 topTreeNodeList.add(treeNode); } else { // 叶子节点 if (allTreeNodeChildrenMap.containsKey(getParentIdCallback.call(treeNode))) { // 当父节点的子集实例存在,则把自个儿丢进去 allTreeNodeChildrenMap.get(getParentIdCallback.call(treeNode)).add(treeNode); } else { // 当父节点的子集实例不存在,提前实例化它,并把自个儿丢进去 List<T> parentChildrenList = new ArrayList<>(); parentChildrenList.add(treeNode); allTreeNodeChildrenMap.put(getParentIdCallback.call(treeNode), parentChildrenList); } } }); return topTreeNodeList; }
代码大致思路如下:
1.遍历每个节点时首先进行children节点list的关联,如果该节点的children节点还未初始化,则初始化并建立关联
2.根节点将自己放入根节点list中作为返回结果
3.叶子节点将自己放入父节点children list中,如果还未实例化则提前实例化它
使用方式如下:
TreeUtil.lambdaGenerateTree(treeNodeList,
TreeNode::getId,
TreeNode::getParentId,
TreeNode::setChildren,
-1L)
转载自:https://blog.csdn.net/qq_37720936/article/details/126409247