一、前提 pId需要傳入用來確認第一級的父節點,而且pId可以為null。 樹實體類必須實現:TreeNode介面 MyTreeVo必須有這三個屬性:id、pId、children 可以根據不同需求,配置TreeNode和MyTreeVo中固定的屬性 二、代碼 定義TreeNode介面 public ...
一、前提
- pId需要傳入用來確認第一級的父節點,而且pId可以為null。
- 樹實體類必須實現:TreeNode介面
- MyTreeVo必須有這三個屬性:id、pId、children
- 可以根據不同需求,配置TreeNode和MyTreeVo中固定的屬性
二、代碼
- 定義TreeNode介面
public interface TreeNode {
String getId();
String getpId();
List getChildren();
}
- 需要將pId作為參數傳入,在方法中添加一個pId參數,用於確認第一級的父節點。
-- 這個示例代碼中,buildTree方法接收兩個參數,一個是泛型類型的參數List,另一個是pId,用於確認第一級的父節點。在找到所有的根節點後,我們需要對每個根節點調用buildChildren方法,遞歸構建子節點。
-- 以便支持傳入的pId作為頂級節點
public class TreeBuilder {
/**
* @param nodes 需要構建的nodes,不要繼承 TreeNode,且需要有 TreeNode 下的三個方法
* @param pId 父id。為null則是所有pid為null的是頂級節點;不為null,則是從給的pId往下查詢並構建樹
**/
public static <T extends TreeNode> List<T> buildTree(List<T> nodes, String pId) {
List<T> roots = new ArrayList<>();
for (T node : nodes) {
if (node.getId().equals(pId) || (node.getParentId() == null && (pId == null || pId.equals(node.getId())))) {
roots.add(node);
}
}
for (T root : roots) {
buildChildren(root, nodes);
}
return roots;
}
private static <T extends TreeNode> void buildChildren(T node, List<T> nodes) {
for (T child : nodes) {
if (child.getParentId() != null && child.getParentId().equals(node.getId())) {
node.getChildren().add(child);
buildChildren(child, nodes);
}
}
}
}
- 構建到幾級
-- 如果再增加一個參數,構建到樹的第幾層該如何實現?
-- 根據需求,如果增加一個參數來控制構建到樹的第幾層,可以在buildChildren方法中添加一個level參數,用於記錄當前節點的層數。在遞歸構建子節點時,如果當前節點的層數小於指定的層數,則繼續遞歸構建子節點,否則停止遞歸。以下是修改後的Java示例代碼:
public class TreeBuilder {
/**
* @param level 級別 從1開始。1是最頂層
**/
public static <T extends TreeNode> List<T> buildTree(List<T> nodes, String pId, int level) {
List<T> roots = new ArrayList<>();
for (T node : nodes) {
if (node.getId().equals(pId) || (node.getParentId() == null && (pId == null || pId.equals(node.getId())))) {
roots.add(node);
}
}
for (T root : roots) {
buildChildren(root, nodes, level, 1);
}
return roots;
}
private static <T extends TreeNode> void buildChildren(T node, List<T> nodes, int level, int currentLevel) {
if (currentLevel >= level) {
return;
}
for (T child : nodes) {
if (child.getParentId() != null && child.getParentId().equals(node.getId())) {
if (node.getChildren() == null) {
node.setChildren(new ArrayList<>());
}
node.getChildren().add(child);
buildChildren(child, nodes, level, currentLevel + 1);
}
}
}
}
三、使用
1、實現TreeNode介面
public class MyTreeVo implements TreeNode {
/**
* 主鍵
*/
private String id;
/**
* 父節點ID
*/
private String pId;
/**
* 子級
*/
private List<MyTreeVo> children = Lists.newArrayList();
//其他屬性……
public List<MyTreeVo> getChildren() {
return children;
}
public String getId() {
return id;
}
public String getpId() {
return pId;
}
//其他屬性的getter、setter……
2、使用
-- pId可以傳入null,也可以傳入需要從哪個節點(X)開始構造的 X的id
-- pId比如可以傳入3、樣例中的 “二、噢噢噢噢”的id=“e6ee51485389495cb923a122be800012”。然後構建出來的,就是“二、噢噢噢噢”的下級樹
List<MyTreeVo> tree = TreeUtilQz.buildTree(vos,null);
//tree就是構建好的樹結構數據
3、樣例
{
"data": [
{
"id": "e6ee51485389495cb923a122be800011",
"pId": "",
"name": "一、鋼管鋼管",
"children": [
{
"id": "e6ee51485389495cb923a122be800014",
"pId": "e6ee51485389495cb923a122be800011",
"name": "(二)嘎嘎嘎嘎嘎",
"children": []
},
{
"id": "e6ee51485389495cb923a122be800013",
"pId": "e6ee51485389495cb923a122be800011",
"name": "(一)頂頂頂頂",
"children": []
}
]
},
{
"id": "e6ee51485389495cb923a122be800012",
"pId": "",
"name": "二、噢噢噢噢",
"children": [
{
"id": "e6ee51485389495cb923a122be800015",
"pId": "e6ee51485389495cb923a122be800012",
"name": "二的下級",
"children": [
{
"id": "e6ee51485389495cb923a122be800016",
"pId": "e6ee51485389495cb923a122be800015",
"name": "二的下級的下級",
"children": []
}
]
}
]
}
]
}