java中使用递归快速构建树形数据结构
1,数据表设计
在设计表时每个记录中应添加parentId字段,用于标识父子关系。
2,实体类
public class Entity {
private Long id;
private Long parentId;
private List<Entity> children = Lists.newArrayList();
// 省略其他属性及get、set方法
}
3,service
// 常量 标识第一层级的父id
private final static Long ROOT_PARENT_ID = 0L;
/**
* 获取树形结构
* @param condition 筛选条件
* @return
*/
public List<Entity> loadTreeData(Condition condition) {
List<Entity> entityList = this.dealTreeData(ROOT_PARENT_ID,condition);
return entityList;
}
private List<Entity> dealTreeData(Long parentId,condition condition){
// 获取所有的数据表记录
List<Entity> allItems = EntityMapper.getAllItems();
if(CollectionUtils.isEmpty(allItems)) {
return Lists.newArrayList();
}
// 递归方法
List<Entity> tree = this.getTree(allItems, parentId);
// 条件筛选
this.treeMatch(tree,condition);
return tree;
}
private List<Entity> getTree(List<Entity> allItems,Long parentId){
List<Entity> tree = new ArrayList<>();
for(Entity entity:allItems){
if(entity.getParentId() == parentId){
entity.setChildren(getTree(allItems,entity.getId()));
tree.add(entity);
}
}
return tree;
}
public void treeMatch(List<Entity> allTree, condition condition){
Iterator<Entity> iter = allTree.iterator();
while (iter.hasNext()){
// 获取当前遍历到的目录
Entity entity = iter.next();
boolean shouldRemove = true;
// 如果当前目录名称包含关键字,则什么也不做(不移除),否则就看下一级
if(StringUtils.hasText(condition.getCondition1()) && !entity.getCondition1().equals(condition.getCondition1())){
// 取出下一级目录集合
List<Entity> childrenList = entity.getChildren();
// 递归
if(!CollectionUtils.isEmpty(childrenList)){
treeMatch(childrenList,condition);
}
} else if(StringUtils.hasText(condition.getCondition2()) && !entity.getCondition2().equals(condition.getCondition2())){
// 取出下一级目录集合
List<Entity> childrenList = entity.getChildren();
// 递归
if(!CollectionUtils.isEmpty(childrenList)){
treeMatch(childrenList,condition);
}
} else {
shouldRemove = false;
}
// 下一级目录看完了,如果下一级目录全部被移除,则移除当前目录
if(CollectionUtils.isEmpty(entity.getItems()) && shouldRemove){
iter.remove();
}
}
}