list轉tree遞歸轉換
/** * 遞歸遍歷節點 * @param sourceList * @param parentCode * @return */ public List<Office> findChildrenList(List<Office> sourceList, String parentCode) { List<Office> treeList = new ArrayList<>(); //獲取到所有parentCode的子節點 for(Office item:sourceList) { if (parentCode.equals(item.getParentCode())) { treeList.add(item); //遞歸遍歷該子節點的子節點列表 item.setChildList(this.findChildrenList(sourceList,item.getOfficeCode())); } } return treeList; }
假設有列表有n個元素要組成一顆樹,時間復雜度為O(n2), 每次遞歸都會創建一個treeList對象,空間復雜度為O(n)
這個遞歸可能當數據量太大時會造成方法棧內存溢出,不是很想使用這個方法。
雙重for循環轉tree(改進)
/** * 部門列表數據轉換成樹結構 * 一次性把所有根節點獲取到,然后再獲取 * * @param list * @param parentCode * @return */ public List<Office> convertTree(List<Office> list, String parentCode) { List<Office> trees = new ArrayList<>(); for (Office item : list) { //獲取到根節點 if (parentCode.equals(item.getParentCode())) { trees.add(item); } //遍歷獲取所有節點下的子節點數據,去除子節點列表中的重復數據 for (Office it : list) { if (it.getParentCode().equals(item.getId())) { if (item.getChildList() == null) { item.setChildList(new ArrayList<Office>()); } boolean isPut = true; for (Office childItem : item.getChildList()) { if (it.getOfficeCode().equals(childItem.getOfficeCode())) { isPut = false; } } if (isPut) { item.getChildList().add(it); } } } } return trees; }
上面雙重for循環,總的來及應該算三重for循環,最外層循環的作用是,獲取到根節點為parentCode的字節點作為樹字節的root樹根節點。
還有一個作用是,遍歷所有節點的子節點列表,
第二層for循環就是用來查找節點的字節點。
而第三層循環是用來去去除子節點列表中的重復數據。因為當List<Office> list是被緩存到內存中時,再次將這個list數據進行樹轉換就會造成子節點數據重復
參考資料
java list 轉樹 tree 的三種寫法:https://blog.csdn.net/jcroad/article/details/79735790#commentBox