用於生成樹狀的層級結構
- 根據情況設置獲取id fid的方法買那個和setChildren方法名。
- 默認的根節點爲0,即傳入的List數據必須包含id爲0的數據,不然返回的是空list,或者自己設置默認的根節點。
- 向下遍歷時獲取所有數據。
- 向上只是一條樹上的數據,即找該子節點的上級。上上級。。。。此時根節點爲最下面的那條數據。
public class MenuTreeUtils<T> {
private List<T> treeList;
//獲取fid 的方法名
private String getFidMethod = "getFid";
//獲取id 的方法名
private String getIdMethod = "getId";
//setChildren 的方法名
private String setChildrenMethod = "setChildren";
//根節點
private String root = "0";
/**
* 向下子節點列表
*/
private List<T> downList = new ArrayList<>();
/**
* 向上子節點列表
*/
private List<T> upList = new ArrayList<>();
public MenuTreeUtils(List<T> list) {
this.treeList = list;
}
/**
* @param list 列表
* @param getFidMethod 獲取父id的方法名稱
* @param getIdMethod 獲取id的方法名稱
* @param setChildrenMethod 設定子樹的方法名稱
* @param root 根節點
*/
public MenuTreeUtils(List<T> list, String getFidMethod, String getIdMethod, String setChildrenMethod, String root) {
this.treeList = list;
this.getFidMethod = getFidMethod;
this.getIdMethod = getIdMethod;
this.setChildrenMethod = setChildrenMethod;
this.root = root;
}
/**
*構建樹狀結構
* @return
*/
public List<T> buildTree(boolean downList) {
List<T> treeTs = new ArrayList<>();
for (T tNode : Objects.requireNonNull(getRootNode(root))) {
if(downList){
this.downList.add(tNode);
}
else {
this.upList.add(tNode);
}
buildChildTree(tNode, downList);
treeTs.add(tNode);
}
return treeTs;
}
/**
* 獲取向上向下的子樹列表
* @param downList 是否獲取向下的列表
* @return
*/
public List<T> getList(boolean downList) {
if(this.downList.isEmpty() && this.upList.isEmpty()) {
buildTree(downList);
}
setChildNull(this.downList);
setChildNull(this.upList);
return downList ? this.downList : this.upList;
}
/**
* 將children設置爲null
* @param tNode 數據列表
* @return
*/
private void setChildNull(List<T> tNode){
for(T node : tNode) {
try {
Method method = node.getClass().getDeclaredMethod(setChildrenMethod, List.class);
method.invoke(node, Collections.EMPTY_LIST);
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
/**
* 向下構建子樹
*
* @param pNode 樹節點
* @return 子樹
*/
private T buildChildTree(T pNode, boolean downList) {
try {
List<T> childTs = new ArrayList<>();
for (T tNode : treeList) {
//如果是向下遍歷 獲取fid 是否爲pNode的id 向上 獲取Id是否爲pNode的fid
Method method = tNode.getClass().getMethod(downList ? getFidMethod : getIdMethod);
String fid = String.valueOf(method.invoke(tNode));
String id = String.valueOf(pNode.getClass().getMethod(downList ? getIdMethod : getFidMethod).invoke(pNode));
if (fid.equals(id)) {
if(downList){
this.downList.add(tNode);
}
else {
this.upList.add(tNode);
}
childTs.add(buildChildTree(tNode, downList));
}
}
if (childTs.isEmpty()) {
return pNode;
}
//爲pNote 設定子節點的值
Method method = pNode.getClass().getDeclaredMethod(setChildrenMethod, List.class);
method.invoke(pNode, childTs);
return pNode;
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
return pNode;
}
}
/**
* 獲取根節點
*
* @return 根節點列表
*/
private List<T> getRootNode(String root) {
try {
List<T> rootLists = new ArrayList<T>();
for (T tNode : treeList) {
Method method = tNode.getClass().getMethod(getIdMethod);
String id = String.valueOf(method.invoke(tNode));
if (id.equals(root)) {
rootLists.add(tNode);
}
}
return rootLists;
} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
return null;
}
}
}