TreeNode.java
import lombok.Data;
import java.util.List;
@Data
public class TreeNode<T> {
/**
* 節點編號
*/
private String id;
/**
* 父節點編號
*/
private String pid;
/**
* 節點名稱
*/
private String title;
/**
* 數據
*/
private T data;
/**
* 子節點
*/
private List<TreeNode<T>> children;
}
TreeUtil.java
import TreeNode;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.PropertyAccessorFactory;
import java.util.*;
import java.util.stream.Collectors;
/**
* @author
* @date
*/
public class TreeUtil {
/**
* 將List構建成前臺展示樹的格式(根節點,層層包含所有子節點)
* @param list 樹形結構列表
* @param idName 節點編號
* @param pidName 父節點編號
* @param titleName 節點名稱
* @param <T>
* @return
*/
public static <T> List<TreeNode<T>> buildTree(List<T> list, String idName, String pidName, String titleName) {
// 將list構建成樹節點的樣式
List<TreeNode<T>> treeNodes = buildTreeNodes(list, idName, pidName, titleName);
// 獲取根節點列表
List<TreeNode<T>> rootNodes = getTreeRootNodes(treeNodes);
// 迭代遞歸出根節點下所有子節點
Map<String, List<TreeNode<T>>> pidGroup = treeNodes.stream().collect(Collectors.groupingBy(TreeNode::getPid));
Iterator<TreeNode<T>> it = rootNodes.iterator();
while (it.hasNext()) {
setChildNodes(pidGroup, it.next());
}
return rootNodes;
}
/**
* 獲取根節點列表
* @param list
* @return
*/
private static <T> List<TreeNode<T>> getTreeRootNodes(List<TreeNode<T>> list) {
// 獲取所有節點id
Set<String> idSet = list.stream().map(TreeNode::getId).collect(Collectors.toSet());
// 篩選出所有根節點(如果父節點不在節點id列表上則表示該節點爲父節點)
List<TreeNode<T>> rootNodes = list.stream().filter(treeNode -> !idSet.contains(treeNode.getPid())).collect(Collectors.toList());
return rootNodes;
}
/**
* 設置所有子節點
* @param pidGroupt
* @param parentNode
* @param <T>
*/
private static <T> void setChildNodes(Map<String, List<TreeNode<T>>> pidGroupt, TreeNode<T> parentNode) {
// 獲取父節點直接下掛的所有子節點
List<TreeNode<T>> children = pidGroupt.get(parentNode.getId());
if (CollectionUtils.isNotEmpty(children)) {
// 迭代每個子節點,爲每個子節點設置它們直接下掛的所有子節點
Iterator<TreeNode<T>> iterator = children.iterator();
while (iterator.hasNext()) {
setChildNodes(pidGroupt,iterator.next());
}
parentNode.setChildren(children);
}
}
/**
* 將List構建成樹節點的樣式(多個節點)
* @param list
* @param idName
* @param pidName
* @param titleName
* @param <T>
* @return
*/
private static <T> List<TreeNode<T>> buildTreeNodes(List<T> list, String idName, String pidName, String titleName) {
List<TreeNode<T>> treeNodes = new ArrayList<>();
// 將list構建成樹節點的樣式
for (T item:list) {
treeNodes.add(buildTreeNode(item, idName, pidName, titleName));
}
return treeNodes;
}
/**
* 將對象構建成樹節點的樣式(單個節點)
* @param obj
* @param idName
* @param pidName
* @param titleName
* @return
*/
private static TreeNode buildTreeNode(Object obj, String idName, String pidName, String titleName){
// 獲取對象屬性值
BeanWrapper beanWrapper = PropertyAccessorFactory.forBeanPropertyAccess(obj);
TreeNode treeNode = new TreeNode();
treeNode.setId((String) beanWrapper.getPropertyValue(idName));
treeNode.setPid((String) beanWrapper.getPropertyValue(pidName));
treeNode.setTitle((String) beanWrapper.getPropertyValue(titleName));
treeNode.setData(obj);
return treeNode;
}
}