VO主要结构
@Data
public class AmItemClassifyStandardTreeVO implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 主键GUID
*/
private String guid;
/**
* 项目分类CODE
*/
private String itemClassifyCode;
/**
* 项目父级分类CODE
*/
private String parentItemClassifyCode;
/**
* 层级
*/
private String level;
/**
* 子级
*/
private List<AmItemClassifyStandardTreeVO> children;
}
将list集合转换为树型结构
public class Test{
// 将数据库中查询出来的list集合传入此方法即可获得排成树形结构的list集合。
public List<AmItemClassifyStandardTreeVO> createTree(List<AmItemClassifyStandardTreeVO> voList) {
List<AmItemClassifyStandardTreeVO> treeVOS = voList.stream().filter(item -> StringUtils.equals((item.getParentItemClassifyCode()),"root"))
.map(item -> {
item.setChildren(getChildren(item, voList));
return item;
}).collect(Collectors.toList());
return treeVOS;
}
/**
* 循环调用遍历子级考勤类型
* @param amItemClassifyStandardTreeVO
* @param list
* @return
*/
private List<AmItemClassifyStandardTreeVO> getChildren(AmItemClassifyStandardTreeVO amItemClassifyStandardTreeVO,List<AmItemClassifyStandardTreeVO> list){
List<AmItemClassifyStandardTreeVO> res = list.stream().filter(item -> StrUtil.equals(item.getParentItemClassifyCode(),amItemClassifyStandardTreeVO.getItemClassifyCode()))
.map(item -> {
item.setChildren(getChildren(item, list));
return item;
}).collect(Collectors.toList());
return res;
}
}
java树结构模糊查询
整体思路,查出数据库的数据,将集合转换为tree结构,即上面的方法,再对树进行模糊查询,具体代码如下:
/**
* 分类树查询
* @param itemClassifyName
* @return
*/
@Override
public List<AmItemClassifyStandardTreeVO> getAttendanceItemTree(String itemClassifyName) {
List<AmAdItemClassifyStandard> amAdItemClassifyStandardList = this.baseMapper.selectList(new LambdaQueryWrapper<>());
List<AmItemClassifyStandardTreeVO> voList = BeanCopyUtils.copyList(amAdItemClassifyStandardList, AmItemClassifyStandardTreeVO.class);
List<AmItemClassifyStandardTreeVO> treeVOS = voList.stream().filter(item -> StringUtils.equals((item.getParentItemClassifyCode()),"root"))
.map(item -> {
item.setChildren(getChildren(item, voList));
return item;
}).collect(Collectors.toList());
if (StringUtils.isNotBlank(itemClassifyName)){
//对树结构进行模糊查询
this.filterTreeByKeyWord(treeVOS,itemClassifyName);
}
return treeVOS;
}
/**
* 循环调用遍历子级考勤类型
* @param amItemClassifyStandardTreeVO
* @param list
* @return
*/
private List<AmItemClassifyStandardTreeVO> getChildren(AmItemClassifyStandardTreeVO amItemClassifyStandardTreeVO,List<AmItemClassifyStandardTreeVO> list){
List<AmItemClassifyStandardTreeVO> res = list.stream().filter(item -> StrUtil.equals(item.getParentItemClassifyCode(),amItemClassifyStandardTreeVO.getItemClassifyCode()))
.map(item -> {
item.setChildren(getChildren(item, list));
return item;
}).collect(Collectors.toList());
return res;
}
/**
* 再通过树结构去模糊查询
* @param data
* @param itemClassifyName
* @return
*/
private List<AmItemClassifyStandardTreeVO> filterTreeByKeyWord(List<AmItemClassifyStandardTreeVO> data, String itemClassifyName) {
if (!ListUtils.isNotEmpty(data)) {
return data;
}
filterByName(data, itemClassifyName);
return data;
}
/**
* 递归方法
* @param list 任意层级的节点
* @param itemClassifyName 关键字
*/
private void filterByName(List<AmItemClassifyStandardTreeVO> list, String itemClassifyName){
Iterator<AmItemClassifyStandardTreeVO> parent = list.iterator();
while (parent.hasNext()){
//当前节点
AmItemClassifyStandardTreeVO standardTreeVO = parent.next();
if (StrUtil.isNotEmpty(itemClassifyName) && !standardTreeVO.getItemClassifyName().contains(itemClassifyName)) {
//当前节点不包含关键字,继续遍历下一级
// 取出下一级节点
List<AmItemClassifyStandardTreeVO> children = standardTreeVO.getChildren();
// 递归
if (ListUtils.isNotEmpty(children)) {
filterByName(children, itemClassifyName);
}
//下一级节点都被移除了,那么父节点也移除,因为父节点也不包含关键字
if (!ListUtils.isNotEmpty(standardTreeVO.getChildren())) {
parent.remove();
}
} else {
//当前节点包含关键字,继续递归遍历
//子节点递归如果不包含关键字则会进入if分支被删除
List<AmItemClassifyStandardTreeVO> children = standardTreeVO.getChildren();
// 递归
if (ListUtils.isNotEmpty(children)) {
filterByName(children, itemClassifyName);
}
}
}
}
根据子节点查询所有父节点:
我们在实际开发过程中,可能会遇到根据子节点反查出父节点的需求,可以参考以下代码:
/**
* 根据字节点遍历出所有父节点
* @param amAdItemClassifyStandard 子节点
* @param allList 所有节点
* @param parentList 根据子节点反查出的父节点及当前子节点
*/
public void getParentItemClassify(AmAdItemClassifyStandard amAdItemClassifyStandard,List<AmAdItemClassifyStandard> allList,List<AmAdItemClassifyStandard> parentList) {
// 查到root节点,结束方法,并保存到parentList集合中
if (StringUtils.equals(amAdItemClassifyStandard.getParentItemClassifyCode(),"root")) {
parentList.add(amAdItemClassifyStandard);
return;
}
// 遍历所有数据中的数据,找到父节点
AmAdItemClassifyStandard tblAmAdItemClassifyStandard = allList.stream().filter(
e -> Objects.equals(e.getItemClassifyCode(), amAdItemClassifyStandard.getParentItemClassifyCode())
).findFirst().get();
parentList.add(amAdItemClassifyStandard);
// 递归调用
this.getParentItemClassify(tblAmAdItemClassifyStandard,allList,parentList);
}
再利用之前将集合转换为Tree结构的方法将parentList集合转换为树结构