public List<DeptVO> tree(String tenantId) { return ForestNodeMerger.merge(baseMapper.tree(tenantId)); }
baseMapper.tree(tenantId)为目标数据源
ForestNodeMerger 工具类
import java.util.List;
public class ForestNodeMerger {
public ForestNodeMerger() {
}
public static <T extends INode<T>> List<T> merge(List<T> items) {
ForestNodeManager<T> forestNodeManager = new ForestNodeManager(items);
items.forEach((forestNode) -> {
if (forestNode.getParentId() != 0L) {
INode<T> node = forestNodeManager.getTreeNodeAt(forestNode.getParentId());
if (node != null) {
node.getChildren().add(forestNode);
} else {
forestNodeManager.addParentId(forestNode.getId());
}
}
});
return forestNodeManager.getRoot();
}
}
ForestNodeManager 工具类
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class ForestNodeManager<T extends INode<T>> {
private final ImmutableMap<Long, T> nodeMap;
private final Map<Long, Object> parentIdMap = Maps.newHashMap();
public ForestNodeManager(List<T> nodes) {
this.nodeMap = Maps.uniqueIndex(nodes, INode::getId);
}
public INode<T> getTreeNodeAt(Long id) {
return this.nodeMap.containsKey(id) ? (INode)this.nodeMap.get(id) : null;
}
public void addParentId(Long parentId) {
this.parentIdMap.put(parentId, "");
}
public List<T> getRoot() {
List<T> roots = new ArrayList();
this.nodeMap.forEach((key, node) -> {
if (node.getParentId() == 0L || this.parentIdMap.containsKey(node.getId())) {
roots.add(node);
}
});
return roots;
}
}
INode<T> 接口
import java.io.Serializable;
import java.util.List;
public interface INode<T> extends Serializable {
Long getId();
Long getParentId();
List<T> getChildren();
default Boolean getHasChildren() {
return false;
}
}
DeptVO 要继承INode接口
@Data @EqualsAndHashCode(callSuper = true) @ApiModel(value = "DeptVO对象", description = "DeptVO对象") public class DeptVO extends Dept implements INode<DeptVO> { private static final long serialVersionUID = 1L; /** * 主键ID */ @JsonSerialize(using = ToStringSerializer.class) private Long id; //这三个为INode里的属性 /** * 父节点ID */ @JsonSerialize(using = ToStringSerializer.class) private Long parentId; /** * 子孙节点 */ @JsonInclude(JsonInclude.Include.NON_EMPTY) private List<DeptVO> children; /** * 是否有子孙节点 */ @JsonInclude(JsonInclude.Include.NON_EMPTY) private Boolean hasChildren; @Override public List<DeptVO> getChildren() { if (this.children == null) { this.children = new ArrayList<>(); } return this.children; } /** * 上级机构 */ private String parentName; /** * 机构类型名称 */ private String deptCategoryName;