父子节点创建树问题

问题:

类似如下部门列表,部门下有子部门,要求创建树结构并且按照部门id排序即单层结构变多层结构:

单层部门列表

```json
[
  {
    "id": 44116841,
    "name": "测试部",
    "parentId": 56188932
  },
  {
    "id": 56104925,
    "name": "飞轮储能事业部",
    "parentId": 1
  },
  {
    "id": 56121882,
    "name": "高速电机部",
    "parentId": 56104925
  },
  {
    "id": 44941198,
    "name": "项目管理部",
    "parentId": 1
  },
  {
    "id": 35232631,
    "name": "视觉算法",
    "parentId": 19693688
  },
  {
    "id": 17387338,
    "name": "人力行政部",
    "parentId": 1
  },
  {
    "id": 35197588,
    "name": "行政",
    "parentId": 17387338
  },
  {
    "id": 19693688,
    "name": "人工智能部",
    "parentId": 56188932
  },
  {
    "id": 35193567,
    "name": "人力资源",
    "parentId": 17387338
  },
  {
    "id": 56122856,
    "name": "结构部",
    "parentId": 56104925
  },
  {
    "id": 54197060,
    "name": "系统平台部",
    "parentId": 56188932
  },
  {
    "id": 17387341,
    "name": "财务部",
    "parentId": 1
  },
  {
    "id": 56188932,
    "name": "机器人事业部",
    "parentId": 1
  },
  {
    "id": 35203611,
    "name": "自然语言算法",
    "parentId": 19693688
  }
]
```

多层部门列表

```json
[
  {
    "id": 17387338,
    "parentId": 1,
    "name": "人力行政部",
    "departments": [
      {
        "id": 35193567,
        "parentId": 17387338,
        "name": "人力资源"
      },
      {
        "id": 35197588,
        "parentId": 17387338,
        "name": "行政"
      }
    ]
  },
  {
    "id": 17387341,
    "parentId": 1,
    "name": "财务部"
  },
  {
    "id": 44941198,
    "parentId": 1,
    "name": "项目管理部"
  },
  {
    "id": 56104925,
    "parentId": 1,
    "name": "飞轮储能事业部",
    "departments": [
      {
        "id": 56121882,
        "parentId": 56104925,
        "name": "高速电机部"
      },
      {
        "id": 56122856,
        "parentId": 56104925,
        "name": "结构部"
      }
    ]
  },
  {
    "id": 56188932,
    "parentId": 1,
    "name": "机器人事业部",
    "departments": [
      {
        "id": 19693688,
        "parentId": 56188932,
        "name": "人工智能部",
        "departments": [
          {
            "id": 35203611,
            "parentId": 19693688,
            "name": "自然语言算法"
          },
          {
            "id": 35232631,
            "parentId": 19693688,
            "name": "视觉算法"
          }
        ]
      },
      {
        "id": 44116841,
        "parentId": 56188932,
        "name": "测试部"
      },
      {
        "id": 54197060,
        "parentId": 56188932,
        "name": "系统平台部"
      }
    ]
  }
]

对于这个问题首先想到的是,递归求出子列表,步骤如下

  1. 新建实体类Department,如下:
public class Department {

    private long id;

    private long parentId;

    private String name;
    
    @JsonInclude(Include.NON_NULL) 
    List<Department> departments;


    //get set方法省略

}

     2.递归解法如下:

    public static void main(String[] args) throws Exception{
    	
		// dlist 为单层结构
		
		List<Department> result = new ArrayList<Department>();
		for (Department department : dlist) {
			if(department.getParentId() == 1L){
				getChildList(dlist,department);
				result.add(department);
			}
		}
		
		//sort  Java 8 的 Stream API 排序
		List<Department> resultSort = result.stream().sorted(Comparator.comparing(Department::getId)).collect(Collectors.toList());
		String resultStr =  mapper.writeValueAsString(resultSort);
		System.out.println(resultStr);
    }
    
    // 递归获取子列表
    public static void getChildList(List<Department> dlist,Department department){
    	List<Department> list  = new ArrayList<Department>();
    	for (Department de : dlist) {
			if(de.getParentId() == department.getId()){
				list.add(de);
				//sort
				List<Department> listSort = list.stream().sorted(Comparator.comparing(Department::getId)).collect(Collectors.toList());
				department.setDepartments(listSort);;
				getChildList(dlist,de);
			}
		}
    	
    }

上面解法可用,但时间复杂度较高,可用下面的解法求解

        Map<Long,List<Department>> depGroup = new HashMap<Long,List<Department>>();
		List<Department> result = new ArrayList<Department>();
		for (Department dep : dlist) {
			List<Department> deps = depGroup.get(dep.getParentId());
			if(null == deps){
				deps = new ArrayList<Department>();
				deps.add(dep);
				depGroup.put(dep.getParentId(), deps);
			}else{
				deps.add(dep);
			}
		}
		
		for (Department dep : dlist) {
			List<Department> childList = depGroup.get(dep.getId());
			if(null != childList){
				//sort
				List<Department> listSort = childList.stream().sorted(Comparator.comparing(Department::getId)).collect(Collectors.toList());
				dep.setDepartments(listSort);
			}
			
			if(dep.getParentId() == 1L){
				result.add(dep);
			}
		}
		
		//sort
		List<Department> resultSort = result.stream().sorted(Comparator.comparing(Department::getId)).collect(Collectors.toList());
		String resultStr =  mapper.writeValueAsString(resultSort);
		System.out.println(resultStr);

首先创建一个map,存放pid与子列表,循环单层结构时,先根据dep的pid 取map中的子列表,若无则新建deps子列表,并放入map中。

第二次循环,为dep找到自己的子列表,并相关联上,顺便进行排序操作。

源码提供:点击下载

猜你喜欢

转载自blog.csdn.net/SHIYUN123zw/article/details/81145451