父子節點建立樹問題
阿新 • • 發佈:2018-11-21
問題:
類似如下部門列表,部門下有子部門,要求建立樹結構並且按照部門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": "系統平臺部" } ] } ]
對於這個問題首先想到的是,遞迴求出子列表,步驟如下
- 新建實體類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找到自己的子列表,並相關聯上,順便進行排序操作。
原始碼提供:點選下載