一.简介
最近业务中个场景,行业分级,用到树结构,抽象出一些普通树的场景。
二.示例
代码语言:javascript复制import lombok.Data;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
/**
* @Classname Tree
* @Description TODO
* @Date 2020/2/17 4:06
* @Created by limeng
*/
@Data
public class Tree<T> extends HashMap<String,Object> {
private static final String CHILDREN_T = "children";
private static final String ID_T = "id";
private static final String PARENT_ID = "parentId";
private static final String TREE_LEVEL_T = "treeLevel";
public void setChildren(List<Tree<T>> children){
this.put(CHILDREN_T, children);
}
public List<Tree<T>> getChildren(){
return (List<Tree<T>>) this.get(CHILDREN_T);
}
public void setId(String id){
this.put(ID_T, id);
}
public String getId(){
return (String) this.get(ID_T);
}
public void setParentId(String parentId){
this.put(PARENT_ID, parentId);
}
public String getParentId(){
return (String) this.get(PARENT_ID);
}
public Tree(){}
/***
* 获取节点父子属性对象
* @param node
* @return
* @throws Exception
*/
public void setNodeAttr(T node){
Class nodeClass = node.getClass();
try{
Field treeIdField = nodeClass.getDeclaredField("id");
treeIdField.setAccessible(true);
this.setId((String) treeIdField.get(node));
this.setNode(node);
}catch(Exception e){
e.printStackTrace();
}
}
public void setNode(T node){
Class c = node.getClass();
Field[] fields = c.getDeclaredFields();
for(Field field : fields){
String name = field.getName();
try{
field.setAccessible(true);
this.put(name, field.get(node));
}catch(IllegalAccessException e){
e.printStackTrace();
}
}
}
}
代码语言:javascript复制import lombok.Data;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Classname TreeVO
* @Description TODO
* @Date 2020/2/17 4:14
* @Created by limeng
*/
@Data
public class TreeVO<T> {
/***
* 树的深度
*/
private Integer depth;
/***
* 节点数量
*/
private Integer NumberOfNodes;
/***
* 普通树森林集合
*/
private List<Tree<T>> treeList;
public void setTreeList(List<Tree<T>> list){
Map<String,Tree<T>> idMap=new HashMap<>();
this.setNodeMap(list,idMap);
if(this.treeList == null){
this.treeList =new ArrayList<>();
}
for(Tree<T> tree:list){
String parentId = tree.getParentId();
Tree<T> parentNode = idMap.get(parentId);
//如果找不到此节点的父节点的的话说明此节点为根节点
if(parentNode == null){
this.treeList.add(tree);
}else{
//如果不为空,则说明此节点为当前列表中存在父节点,则将此节点插入
List<Tree<T>> children = parentNode.getChildren();
if(children == null){
children = new ArrayList<>();
children.add(tree);
parentNode.setChildren(children);
}else{
parentNode.getChildren().add(tree);
}
}
}
}
private void setNodeMap(
List<Tree<T>> list,
Map<String, Tree<T>> idMap
){
for(Tree<T> tree : list){
if(tree.getChildren() == null){
tree.setChildren(new ArrayList<Tree<T>>());
}
idMap.put(tree.getId(), tree);
}
}
private void setParentIdMap(
List<TreeNodeAttrDTO<T>> list,
Map<Integer, Tree<T>> parentIdMap
){
}
}
代码语言:javascript复制import com.knowlegene.core.model.BaseIncrementIdModel;
import java.util.Date;
/**
* 电路树
* @Classname ElectricTree
* @Description TODO
* @Date 2020/3/2 11:16
* @Created by limeng
*/
public class ElectricTree extends BaseIncrementIdModel {
private String label;
private String parentId;
private String description;
private Integer sort;
private Date createDate;
private Date updateDate;
private String nodeType;
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public String getParentId() {
return parentId;
}
public void setParentId(String parentId) {
this.parentId = parentId;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Integer getSort() {
return sort;
}
public void setSort(Integer sort) {
this.sort = sort;
}
public Date getCreateDate() {
return createDate;
}
public void setCreateDate(Date createDate) {
this.createDate = createDate;
}
public Date getUpdateDate() {
return updateDate;
}
public void setUpdateDate(Date updateDate) {
this.updateDate = updateDate;
}
public String getNodeType() {
return nodeType;
}
public void setNodeType(String nodeType) {
this.nodeType = nodeType;
}
}
上述是树抽象类构建和实体,下面一些查询,组建树的过程。
代码语言:javascript复制 /**
* 查询所有子节点
*
* @param id
* @return
*/
@Override
public List<Tree<ElectricTreeDTO>> queryByAllChildList(String id,int levelVal) {
List<Tree<ElectricTreeDTO>> treeList=new ArrayList<>();
int level = 0;
treeList = this.queryByChildList(id,level,levelVal,treeList);
ElectricTree electricTree = this.queryByElectricTreeId(id);
if(electricTree != null){
ElectricTreeDTO electricTreeDTO = new ElectricTreeDTO();
BeanUtil.copyBean(electricTree,electricTreeDTO);
Tree<ElectricTreeDTO> tree =new Tree<>();
tree.setId(id);
tree.setParentId(electricTree.getParentId());
tree.setNode(electricTreeDTO);
treeList.add(tree);
}
return treeList;
}
/**
* 查询多级
* @param id
* @param level
* @return
*/
private List<Tree<ElectricTreeDTO>> queryByChildList(String id, int level,int levelVal,List<Tree<ElectricTreeDTO>> treeList) {
if(level < levelVal && StringUtil.isNotBlank(id)){
ElectricTreeDTO electricTreeDTO = null;
Tree<ElectricTreeDTO> tree =null;
List<Condition> conditionList = new ArrayList<>();
conditionList.add(Condition.parseCondition("parentId_eq").setValue(id));
List<ElectricTree> electricTrees = electricTreeBiz.find(conditionList);
if(!CollectionUtil.isEmpty(electricTrees)){
String id2 = null;
for(ElectricTree electricTree:electricTrees){
id2 = electricTree.getId();
if(StringUtil.isEmpty(id2)) continue;
tree = new Tree<>();
electricTreeDTO = new ElectricTreeDTO();
BeanUtil.copyBean(electricTree,electricTreeDTO);
tree.setId(id2);
tree.setNode(electricTreeDTO);
tree.setParentId(electricTree.getParentId());
treeList.add(tree);
treeList = this.queryByChildList(id2,level 1,levelVal,treeList);
}
}
}
return treeList;
}
/**
* 组建树
* treeVO = new TreeVO<>();
* treeVO.setTreeList(treeList);
*
**/
上述通过递归查询,可以控制查询到多少层。