菜單目錄,地區表等經常會用tree結構的形式去展示。
1 實體
實體會表現成自我嵌套。
由id指向parentId,形成循環。
2 數據結構
可以看出 segc_id 是子節點,segc_parent_id 是父節點,根節點是 null 也有設置為0的。
1 List轉tree
1.1 MybatisPlus注解 @many 實現
segc_brd_id 這只是無關緊要的狀態查詢條件,最主要的 many= @many 這個注解,childrer的映射之后,他能實現遞歸的效果。
注意的是 @many注解select上的方法名。
網上的信息也比較多。這里提供一種思路,具體實現,可以去深入研究一下,是怎么達到遞歸的效果的。
1.2 遞歸
正常來說,根據表格數據查出來都是List集合。
這里貼上代碼,這里有三個變量, id 和 parentId ,根節點的值.
id指向parentId ,由底層往上開始構建tree結構,最后根節點的值判斷停止迭代。這里的根節點,我們這邊是null。
/** * 使用遞歸方法建樹 */ public List<Rsegmentcategory> buildTreeByRsegmentcategory(List<Rsegmentcategory> tree) { List<Rsegmentcategory> trees = new ArrayList<>(); for (Rsegmentcategory treeNode : tree) { if (treeNode.getSegcParentId() == null) { trees.add(findChildrenByRsegmentcategory(treeNode, tree)); } } return trees; } /** * 遞歸查找子節點 * * @param tree * @return */ public static Rsegmentcategory findChildrenByRsegmentcategory(Rsegmentcategory treeNode, List<Rsegmentcategory> tree) { for (Rsegmentcategory it : tree) { if (treeNode.getSegcId().equals(it.getSegcParentId())) { if (treeNode.getChildren() == null) { treeNode.setChildren(new ArrayList<>()); } treeNode.getChildren().add(findChildrenByRsegmentcategory(it, tree)); } } return treeNode; }
2 tree 轉 List
這里也是迭代的方法。
貼上代碼
這里新建集合接收tree解析后的數據。
不斷迭代,根絕children 是否為空來停止迭代。
/** * 解析樹形結構 * * @param list * @return */ private static List<Rsegmentcategory> toList(List<Rsegmentcategory> list) { List<Rsegmentcategory> result = new ArrayList<>(); for (Rsegmentcategory entity : list) { result.add(entity); List<Rsegmentcategory> child = entity.getChildren(); if (child != null && child.size() > 0) { List<Rsegmentcategory> entityList = toList(child); result.addAll(entityList); } } if (result.size() > 0) { for (Rsegmentcategory entity : result) { entity.setChildren(null); } } return result; }
3 獲取tree的最底層的節點
不知道是不是這樣說,就是由自底層的節點一直向根節點尋找,並且記錄路徑。返回tree結構
差不多是畫圖的這個意思。
同樣貼上代碼
//這是獲取tree結構
List<Rsegmentcategory> allTree = rsegmentcategoryDao.findAllTree(1);
// tree結構放入 map
List<Map> maps = JSONArray.parseArray(JSONUtil.toJsonStr(allTree), Map.class);
//新建一個數據接收
List<Map<String, Object>> lastChildrenList = new ArrayList<>();
//方法
this.getLastChildrens(maps, lastChildrenList, "children");
方法:
/**
* 取出最底層的Children
*
* @param data
* @param childrenList
* @param key
*/
public void getLastChildrens(List<Map> data, List<Map<String, Object>> childrenList, String key) {
if (data == null) {
return;
}
for (Map orgData : data) {
List<Rsegmentcategory> categories = (List<Rsegmentcategory>) orgData.get(key);
if (orgData.containsKey(key) && categories.size() > 0) {
getLastChildrens(JSONArray.parseArray(orgData.get(key).toString(), Map.class), childrenList, key);
} else {
childrenList.add(orgData);
}
}
}
最后將map結構在解析回來
JSONArray jsonArray = new JSONArray();
jsonArray.addAll(lastChildrenList);
//這又變成list 想轉tree可以用上面的轉結構方法
List<Rtagtree> list = jsonArray.toJavaList(Rtagtree.class);
學藝不精,網上縫合。以后有更好的方法在做記錄。
最終效果展示
感覺挺有意思的一次需求,特此記錄。