效果图展示
总结
对于之前的两级树,博主首先想到的是实体类里面进行封装就可以了,并没有采用递归的形式,可后来随着树结构的增加,树的层级也越来越大,这种情况下显然是不可采取的,便想到了采用递归的方式,同时对于搜索也能采用递归的思想,这样对于无论多少层树同样适用,大大提高了工作效率
代码
话不多说,上代码
/**
* 树的展示加搜索
*
* @param map
* @return
*/
@RequestMapping("/findTree")
public R findTree(@RequestBody Map<String, Object> map) {
String keywords = (String) map.get("keywords");
List<TreeVo> treeVos = treeDao.treeKeywords(keywords);
List<String> list = new ArrayList<>();
for (TreeVo treeVo : treeVos) {
String nodeName = treeVo.getNodeName();
list.add(nodeName);
}
List<TreeVo> oneTrees = treeDao.findOneTree();
List<TreeVo> lists = new ArrayList<>();
for (TreeVo oneTree : oneTrees) {
traverse(oneTree);
lists.add(oneTree);
}
if (keywords.isEmpty()) {
return R.ok().setData(lists);
}
List<TreeVo> treeVos1 = screenTree(lists, list);
return R.ok().setData(treeVos1);
}
/**
* 树结构遍历
*
* @param oneTree
*/
public void traverse(TreeVo oneTree) {
List<TreeVo> treeVos = treeDao.findTwoTree(oneTree.getId());
if (treeVos != null) {
for (int i = 0; i < treeVos.size(); i++) {
TreeVo treeVo = treeVos.get(i);
traverse(treeVo);
}
}
oneTree.setTreeVoList(treeVos);
}
/**
* 树形筛选查找
*
* @param treeDtoList 树形集合
* @param idList 筛选条件(可以是其他条件)
* @return 包含的节点数据
*/
public static List<TreeVo> screenTree(List<TreeVo> treeDtoList, List<String> idList) {
//最后返回的筛选完成的集合
List<TreeVo> screeningOfCompleteList = new ArrayList<>();
if (listIsNotEmpty(treeDtoList) && listIsNotEmpty(idList)) {
for (TreeVo treeDto : treeDtoList) {
List<TreeVo> subsetList = treeDto.getTreeVoList();
//递归筛选完成后的返回的需要添加的数据
TreeVo addTreeDto = getSubsetPmsPlanPo(treeDto, subsetList, idList);
if (isNotEmpty(addTreeDto)) {
screeningOfCompleteList.add(addTreeDto);
}
}
return screeningOfCompleteList;
}
return null;
}
/**
* 筛选符合的集合并返回
*
* @param treeDto 树形类
* @param subsetTreeDtoList 子集集合
* @param idList 筛选条件
* @return 筛选成功的类
*/
public static TreeVo getSubsetPmsPlanPo(TreeVo treeDto, List<TreeVo> subsetTreeDtoList, List<String> idList) {
//作为筛选条件的判断值
String nodeName = treeDto.getNodeName();
//有子集时继续向下寻找
if (listIsNotEmpty(subsetTreeDtoList)) {
List<TreeVo> addTreeDtoList = new ArrayList<>();
for (TreeVo subsetTreeDto : subsetTreeDtoList) {
List<TreeVo> subsetList = subsetTreeDto.getTreeVoList();
TreeVo newTreeDto = getSubsetPmsPlanPo(subsetTreeDto, subsetList, idList);
//当子集筛选完不为空时添加
if (isNotEmpty(newTreeDto)) {
addTreeDtoList.add(newTreeDto);
}
}
//子集满足条件筛选时集合不为空时,替换对象集合内容并返回当前对象
if (listIsNotEmpty(addTreeDtoList)) {
treeDto.setTreeVoList(addTreeDtoList);
return treeDto;
//当前对象子集对象不满足条件时,判断当前对象自己是否满足筛选条件,满足设置子集集合为空,并返回当前对象
} else if (listIsEmpty(addTreeDtoList) && idList.contains(nodeName)) {
if (listIsEmpty(addTreeDtoList) && treeDto.getLevel() == 6) {
treeDto.setTreeVoList(null);
}
// treeDto.setTreeVoList(null);
return treeDto;
} else {
//未满足筛选条件直接返回null
return null;
}
} else {
//无子集时判断当前对象是否满足筛选条件
if (idList.contains(nodeName)) {
return treeDto;
} else {
return null;
}
}
}
/**
* 判断集合为空
*
* @param list 需要判断的集合
* @return 集合为空时返回 true
*/
public static boolean listIsEmpty(Collection list) {
return (null == list || list.size() == 0);
}
/**
* 判断集合非空
*
* @param list 需要判断的集合
* @return 集合非空时返回 true
*/
public static boolean listIsNotEmpty(Collection list) {
return !listIsEmpty(list);
}
/**
* 判断对象为null或空时
*
* @param object 对象
* @return 对象为空或null时返回 true
*/
public static boolean isEmpty(Object object) {
if (object == null) {
return (true);
}
if ("".equals(object)) {
return (true);
}
if ("null".equals(object)) {
return (true);
}
return (false);
}
/**
* 判断对象非空
*
* @param object 对象
* @return 对象为非空时返回 true
*/
public static boolean isNotEmpty(Object object) {
if (object != null && !object.equals("") && !object.equals("null")) {
return (true);
}
return (false);
}
public void selectById(Integer id, List<Integer> idList, List<Integer> list) {
//查询数据库等于id的数据
List<TreeVo> childList = treeDao.findTwoTree(id);
//递归查询下一级id,同时将上一次查询结果添加到list集合
childList.forEach(menu -> {
idList.add(menu.getId());
if (menu.getLevel() == 6) {
list.add(menu.getId());
}
this.selectById(menu.getId(), idList, list);
});
}
public void selectByIdFive(Integer id, List<Integer> idList, List<Integer> list) {
//查询数据库等于id的数据
List<TreeVo> childList = treeDao.findTwoTree(id);
//递归查询下一级id,同时将上一次查询结果添加到list集合
childList.forEach(menu -> {
idList.add(menu.getId());
if (menu.getLevel() < 6) {
list.add(menu.getId());
}
this.selectById(menu.getId(), idList, list);
});
}