使用java递归实现列表层级显示
分享,欢迎批评指正,谢谢~
结构类似如下(无限级):
- 工程1
- 子工程1.1
- 孙工程1.1.1
- 孙工程1.1.2
- 子工程1.2
- 子工程1.3
- 子工程1.1
- 工程2
- 子工程2.1
- 孙工程2.1.1
- 孙工程2.1.2
…
- 子工程2.1
model层
//数据库表中字段相同
public class Eng{
private Long engId;
private String engName;
private Long engPid;
//get set自行添加,此处省略
}
自定义DTO类
在model字段基础上加入childrenList
public class EngChildrenDTO{
private Long engId;
private String engName;
private Long engPid;
private List<EngChildrenDTO> childrenList;
//get set自行添加,此处省略
}
service层
public List<EngChildrenDTO> engList() {
//查询出所有的工程(line 1~line5)
//因为本案例使用了MyBatis Generator自动生成model类、dao层的mapper类、*DynamicSqlSupport动态语句支持类
//所以该案例"查询所有工程"时使用MyBatis3 DynamicSql写法,可相应地替换成您项目中使用的其他方式来实现"查询出所有的工程"
SelectStatementProvider render = select(EngDynamicSqlSupport.eng.allColumns())
.from(EngDynamicSqlSupport.eng)
.where(EngDynamicSqlSupport.deleteFlag, isEqualTo(0))
.build().render(RenderingStrategies.MYBATIS3);
List<Eng> allEngs = engMapper.selectMany(render);
//遍历查询出来的所有工程allEngs ,赋值给engChildrenDTO,并add到root
ArrayList<EngChildrenDTO> root = new ArrayList<>();//用于存放所有工程
for (Eng allEng : allEngs) {
EngChildrenDTO engChildrenDTO = new EngChildrenDTO();
BeanUtils.copyProperties(allEng, engChildrenDTO);//给riskEngChildrenDTO赋值
root.add(engChildrenDTO);
}
//遍历root 找到所有的一级工程,add到finalList
List<EngChildrenDTO> finalList = new ArrayList<>();//用于存放一级工程
for (EngChildrenDTO eng : root) {
if (StringUtils.isEmpty(eng.getEngPid())) {//一级工程(pid为空)
finalList.add(eng);
}
}
// 遍历一级工程,为一级工程设置子工程( 调用下方定义的递归体getChild() )
for (EngChildrenDTO eng : finalList) {
eng.setChildrenList(getChild(eng.getEngId(), root));
}
return finalList;
}
//递归体,主方法中进行循环调用
private List<EngChildrenDTO> getChild(Long id, List<EngChildrenDTO> root) {
//遍历传入的root,pid不为空(即不是一级工程) 且此工程pid等于传过来的工程的id时,加入childList
List<EngChildrenDTO> childList = new ArrayList<>(); //用于存放子工程
for (EngChildrenDTO engChildrenDTO : root) {
if (!StringUtils.isEmpty(engChildrenDTO.getEngPid())) {
if (engChildrenDTO.getEngPid().equals(id)) {
childList.add(engChildrenDTO);
}
}
}
//递归终止的条件(没有子工程时)
if (childList.size() == 0) {
return null;
}
//如果有子工程还有子工程,遍历childList,继续进行递归调用
for (EngChildrenDTO engChildrenDTO : childList) {
engChildrenDTO.setChildrenList(getChild(engChildrenDTO.getEngId(), root));
}
return childList;
}
结果展示
{
"status": true,
"data": [
{
"engId": "1388436330181062657",
"engName": "工程1",
"engPid": null,
"childrenList": [
{
"engId": "1390277587912224770",
"engName": "子工程1.1",
"engPid": "1388436330181062657",
"childrenList": [
{
"engId": "1391568088810614785",
"engName": "孙工程1.1",
"engPid": "1390277587912224770",
"childrenList": null
}
]
},
{
"engId": "1390276723344535553",
"engName": "子工程1.2",
"engPid": "1388436330181062657",
"childrenList": null
}
]
},
{
"engId": "1390994842794659842",
"engName": "工程2",
"engPid": null,
"childrenList": [
{
"engId": "1391571581688590337",
"engName": "子工程2.1",
"engPid": "1390994842794659842",
"childrenList": null
},
{
"engId": "1391568182108712961",
"engName": "子工程2.2",
"engPid": "1390994842794659842",
"childrenList": [
{
"engId": "1391572327666483201",
"engName": "孙工程2.2.1",
"engPid": "1391568182108712961",
"childrenList": [
{
"engId": "1392450583207936001",
"engName": "孙工程2.2.2",
"engPid": "1391572327666483201",
"childrenList": null
}
]
}
]
}
]
}
],
"code": 8000000,
"message": "成功",
"txId": "null"
}