package com.estate.expert.admin.utils.tree; import com.estate.expert.admin.enums.BizResultCode; import com.fasterxml.jackson.annotation.JsonIgnore; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; import javax.persistence.Transient; import java.util.*; @ApiModel(value = "树节点") @Data public class TreeNode { @ApiModelProperty(value = "节点id,在同一层级下唯一") private Integer id = 0; @ApiModelProperty(value = "节点名称,同一层级下唯一") private String name; @ApiModelProperty(value = "子节点Id计数器,自增") private int childIdCnt = 0; @ApiModelProperty(value = "节点中的数据") private T data; @ApiModelProperty(value = "节点的路径,全局唯一") private String path; @Transient @JsonIgnore private TreeNode parent; @ApiModelProperty(value = "子节点") public SortedMap> children = new TreeMap<>(); public TreeNode(){ } public TreeNode(String name) { this.name = name; this.id = 0; } public TreeNode(String name, T data) { this.name = name; this.data = data; this.id = 0; } public TreeNode ShadowNode() { TreeNode shadow = new TreeNode<>(this.getName(), this.getData()); shadow.setId(this.getId()); shadow.setPath(this.getPath()); shadow.setData(this.getData()); shadow.setName(this.getName()); return shadow; } public TreeNode addChild(TreeNode child) { children.put(child.getId(), child); return child; } public TreeNode addChild(String name) { return addChild(name, null); } public TreeNode addChild(String name, T data) { for(TreeNode child : children.values()) { BizResultCode.HIERARCHY_NODE_NAME_ALREADY_EXISTS.check(child.getName().equals(name)); } TreeNode child = new TreeNode<>(name, data); child.setId(childIdCnt++); child.setName(name); child.setData(data); child.setParent(this); this.children.put(child.getId(), child); return child; } public void removeChild(Integer id) { children.remove(id); } /** * 获取该节点下所有的路径 * 以及所在分支的路径 */ public List allPaths(){ var list = new ArrayList(); for (var child : children.values()){ list.addAll(child.allPaths()); } list.add(getPath()); var parent = getParent(); while (parent != null){ list.add(parent.getPath()); parent = parent.getParent(); } return list; } /** * 递归查找节点 * 这里,由于树的根节点是单一的 * 根节点的path= "/" */ public void buildPath() { StringBuilder builder = new StringBuilder(); TreeNode node = this; while (true) { var parent = node.getParent(); if(parent == null) { break; } builder.insert(0, node.getId()); builder.insert(0, "/"); node = parent; } if(builder.isEmpty()) { path = "/"; return; } path = builder.toString(); } @JsonIgnore public String getNamePath(){ StringBuilder builder = new StringBuilder(); TreeNode node = this; while (true) { var parent = node.getParent(); if(parent == null) break; builder.insert(0, node.getName()); builder.insert(0, "/"); node = parent; } if(builder.isEmpty()) return "/"; return builder.toString(); } @JsonIgnore public List getNames(){ List names = new ArrayList<>(); TreeNode node = this; while (true) { names.add(node.getName()); var parent = node.getParent(); if(parent == null) break; node = parent; } return names; } @JsonIgnore public int getDepth(){ // 根节点的深度为0 int depth = 0; TreeNode node = this; while (true) { var parent = node.getParent(); if(parent == null) break; depth++; node = parent; } return depth; } @JsonIgnore public List> getLeafNodes() { List> leafNodes = new ArrayList<>(); getLeafNodes(this, leafNodes); return leafNodes; } private void getLeafNodes(TreeNode node, List> leafNodes) { if (node.getChildren().isEmpty()) { leafNodes.add(node); } else { for (TreeNode child : node.getChildren().values()) { getLeafNodes(child, leafNodes); } } } @Override public String toString() { return "TreeNode{" + "path=" + path + ", name='" + name + "', data=" + data + "}" ; } }