场景说明:
在项目实际过程中,经常遇见二维表(数据库表)为树形结构存储数据,但是递归查询需要好多次,特别是数据量大时,变得非常不合适~
以下是项目中,将列表转换组装为树形结构的代码共享~
平铺的数据:
参考代码案例:
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 convertTree(List sysMenuList) { if (sysMenuList == null || sysMenuList.size() <= 0) { return new ArrayList(); } int topSign = -1; List healthSysMenuDTOList = findChildren(sysMenuList, topSign); buildTree(sysMenuList, healthSysMenuDTOList); return healthSysMenuDTOList; } /** * @param sysMenuList * @param parentId * @return */ private static List findChildren(List sysMenuList, int parentId) { // 根据父节点找到子节点,以集合的形式返回 List healthSysMenuDTOList = new ArrayList(); 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 sysMenuList, List sysMenuDTOList) { // 如果存在子节点,再次递归子节点 if (sysMenuDTOList != null && sysMenuDTOList.size() > 0) { for (HealthSysMenuDTO healthSysMenuDTO : sysMenuDTOList) { List subSysMenuDTOList = findChildren(sysMenuList, healthSysMenuDTO.getParentId()); if (subSysMenuDTOList != null && subSysMenuDTOList.size() > 0) { healthSysMenuDTO.setChildren(subSysMenuDTOList); } } } } /** * 排序 * @param healthSysMenuDTOList */ private static void sorted(List healthSysMenuDTOList){ Collections.sort(healthSysMenuDTOList,new Comparator() { @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 sysMenuList = new ArrayList(); // 构建顶层节点,其父节点为"-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 convertTree = convertTree(sysMenuList); System.out.println(convertTree); }}
代码案例的执行效果: