1、tree抽象基类
public abstract class BaseTreeNode implements Serializable {
/**
* 获取当前code
* @return
*/
public abstract String obtainCode();
/**
* 获取父code
* @return
*/
public abstract String obtainParentCode();
/**
* 添加到子集
* @param node
*/
public abstract void add(BaseTreeNode node);
}
2、通用实现类Tree(自定义类只要实现抽象基类就可以)
@Data
public class TreeNode<T> extends BaseTreeNode {
private static final long serialVersionUID = -1586013635569434864L;
/**
* 节点code
*/
private T code;
/**
* 节点名
*/
private String name;
/**
* 父节点code
*/
@JsonIgnore
private T parentCode;
/**
* 子节点
*/
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private List<TreeNode> children = new ArrayList<>();
public TreeNode(){}
public TreeNode(T code,String name,T parentCode){
this.code = code;
this.name = name;
this.parentCode = parentCode;
}
@Override
public String obtainCode() {
return String.valueOf(this.code);
}
@Override
public String obtainParentCode() {
return String.valueOf(this.parentCode);
}
@Override
public void add(BaseTreeNode node) {
this.children.add((TreeNode) node);
}
}
3、tree帮助类
@UtilityClass
public class TreeUtil {
/**
* 获取层级列表
* @param voList
* @return
*/
public List<BaseTreeNode> build(List<BaseTreeNode> voList){
List<BaseTreeNode> returnList = new ArrayList<>();
List<String> tempList = new ArrayList<>();
for (BaseTreeNode t : voList) {
tempList.add(t.obtainCode());
}
for (Iterator<BaseTreeNode> iterator = voList.iterator();iterator.hasNext();){
BaseTreeNode vo = iterator.next();
if(!tempList.contains(vo.obtainParentCode())){
returnList.add(findChildren(voList,vo));
}
}
if(returnList.isEmpty()){
returnList = voList;
}
return returnList;
}
private static BaseTreeNode findChildren(List<BaseTreeNode> voList, BaseTreeNode vo) {
Iterator<BaseTreeNode> it = voList.iterator();
while (it.hasNext()){
BaseTreeNode node = it.next();
String parentCode = node.obtainParentCode();
if(StringUtils.isNotEmpty(parentCode) && vo.obtainCode().equalsIgnoreCase(parentCode)){
if(hasChild(voList,node)){
node = findChildren(voList,node);
}
vo.add(node);
}
}
return vo;
}
private static boolean hasChild(List<BaseTreeNode> voList, BaseTreeNode node) {
return voList.stream().anyMatch(vo -> StringUtils.isNotEmpty(vo.obtainParentCode()) && node.obtainCode().equalsIgnoreCase(vo.obtainParentCode()));
}
}
4、应用
@Override
public List<BaseTreeNode> buildTree(List<DictVo> voList) throws Exception {
List<BaseTreeNode> treeNodes = voList.stream().map(vo -> new TreeNode(vo.getCode(), vo.getName(), vo.getParentCode())).collect(Collectors.toList());
return TreeUtil.build(treeNodes);
}