场景说明:
在项目实际过程中,经常遇见 二维表 (数据库表)为树形结构存储数据,但是递归查询需要好多次,特别是数据量大时,变得非常不合适~
以下是项目中,将列表转换组装为树形结构的代码共享~
平铺的数据:
![Java,List,对象列表,排序,平铺结构转树形结构](/wp-content/uploads/replace/b646bc09b6e727d14c245fbb7888adf5.jpeg)
参考代码案例:
import com.sxmfyy.health.model.system.menu.HealthSysMenu;
import com.sxmfyy.health.model.system.menu.dto.HealthSysMenuDTO;
import org.springframework.beans.BeanUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class TileTreeConverter {
/**
* 算法====>将平铺结构转换为树形结构
* 实现方案====>采用递归方式
*
* @param sysMenuList
* @return
*/
public static List<HealthSysMenuDTO> convertTree(List<HealthSysMenu> sysMenuList) {
if (sysMenuList == null || sysMenuList.size() <= 0) {
return new ArrayList<HealthSysMenuDTO>();
}
int topSign = -1;
List<HealthSysMenuDTO> healthSysMenuDTOList = findChildren(sysMenuList, topSign);
buildTree(sysMenuList, healthSysMenuDTOList);
return healthSysMenuDTOList;
}
/**
* @param sysMenuList
* @param parentId
* @return
*/
private static List<HealthSysMenuDTO> findChildren(List<HealthSysMenu> sysMenuList, int parentId) {
// 根据父节点找到子节点,以集合的形式返回
List<HealthSysMenuDTO> healthSysMenuDTOList = new ArrayList<HealthSysMenuDTO>();
for (HealthSysMenu healthSysMenu : sysMenuList) {
if (parentId == healthSysMenu.getParentId()) {
HealthSysMenuDTO healthSysMenuDTO = new HealthSysMenuDTO();
healthSysMenuDTO.setId(healthSysMenu.getMenuId());
healthSysMenuDTO.setParentId(healthSysMenu.getParentId());
BeanUtils.copyProperties(healthSysMenu, healthSysMenuDTO);
healthSysMenuDTOList.add(healthSysMenuDTO);
}
}
sorted(healthSysMenuDTOList);
return healthSysMenuDTOList;
}
/**
* @param sysMenuList
* @param sysMenuDTOList
* @return
*/
private static void buildTree(List<HealthSysMenu> sysMenuList, List<HealthSysMenuDTO> sysMenuDTOList) {
// 如果存在子节点,再次递归子节点
if (sysMenuDTOList != null && sysMenuDTOList.size() > 0) {
for (HealthSysMenuDTO healthSysMenuDTO : sysMenuDTOList) {
List<HealthSysMenuDTO> subSysMenuDTOList = findChildren(sysMenuList, healthSysMenuDTO.getParentId());
if (subSysMenuDTOList != null && subSysMenuDTOList.size() > 0) {
healthSysMenuDTO.setChildren(subSysMenuDTOList);
}
}
}
}
/**
* 排序
* @param healthSysMenuDTOList
*/
private static void sorted(List<HealthSysMenuDTO> healthSysMenuDTOList){
Collections.sort(healthSysMenuDTOList,new Comparator<HealthSysMenuDTO>() {
@Override
public int compare(HealthSysMenuDTO t1, HealthSysMenuDTO t2) {
if(t1.getSort() > t2.getSort()){
return 1;
}else if(t1.getSort() < t2.getSort()){
return -1;
}
return 0;
}
});
}
/**
* main方法==>测试验证
*
* @param args
*/
public static void main(String[] args) {
List<HealthSysMenu> sysMenuList = new ArrayList<HealthSysMenu>();
// 构建顶层节点,其父节点为"-1"
HealthSysMenu healthSysMenu1001 = new HealthSysMenu();
healthSysMenu1001.setMenuId(1001L);
healthSysMenu1001.setParentId(-1);
healthSysMenu1001.setName("1001");
healthSysMenu1001.setSort(1);
sysMenuList.add(healthSysMenu1001);
HealthSysMenu healthSysMenu1002 = new HealthSysMenu();
healthSysMenu1002.setMenuId(1002L);
healthSysMenu1002.setParentId(-1);
healthSysMenu1002.setName("1002");
healthSysMenu1002.setSort(3);
sysMenuList.add(healthSysMenu1002);
HealthSysMenu healthSysMenu1003 = new HealthSysMenu();
healthSysMenu1003.setMenuId(1003L);
healthSysMenu1003.setParentId(-1);
healthSysMenu1003.setName("1003");
healthSysMenu1003.setSort(2);
sysMenuList.add(healthSysMenu1003);
// 构建节点的子节点
HealthSysMenu healthSysMenu100101 = new HealthSysMenu();
healthSysMenu100101.setMenuId(100101L);
healthSysMenu100101.setParentId(1001);
healthSysMenu100101.setName("100101");
healthSysMenu100101.setSort(1);
sysMenuList.add(healthSysMenu100101);
HealthSysMenu healthSysMenu100102 = new HealthSysMenu();
healthSysMenu100102.setMenuId(100102L);
healthSysMenu100102.setParentId(1001);
healthSysMenu100102.setName("100102");
healthSysMenu100102.setSort(3);
sysMenuList.add(healthSysMenu100102);
HealthSysMenu healthSysMenu100103 = new HealthSysMenu();
healthSysMenu100103.setMenuId(100103L);
healthSysMenu100103.setParentId(1001);
healthSysMenu100103.setName("100102");
healthSysMenu100103.setSort(2);
sysMenuList.add(healthSysMenu100103);
// 转换成树形结构对象
List<HealthSysMenuDTO> convertTree = convertTree(sysMenuList);
System.out.println(convertTree);
}
}
代码案例的执行效果:
![](/wp-content/uploads/replace/e9ba217174765e3d7012727ce5e604fd.jpeg)