一、定义接口,统一规范
public interface TreeNodeBase<T> {
Object getId();
Object getParentId();
List<T> getChildren();
}
二、编写工具类 TreeNodeUtil
public class TreeNodeUtil {
public static final String PARENT_NAME = "parent";
public static final String CHILDREN_NAME = "children";
public static final List<Object> ROOT_NODE_IDS = Collections.singletonList(0l);
public static <T extends TreeNodeBase> List<T> buildTree(List<T> dataList) {
return buildTree(dataList, ROOT_NODE_IDS, (data) -> data, (item) -> true);
}
public static <T extends TreeNodeBase> List<T> buildTree(List<T> dataList, Function<T, T> map) {
return buildTree(dataList, ROOT_NODE_IDS, map, (item) -> true);
}
public static <T extends TreeNodeBase> List<T> buildTree(List<T> dataList, Predicate<T> filter) {
return buildTree(dataList, ROOT_NODE_IDS, (data) -> data, filter);
}
public static <T extends TreeNodeBase> List<T> buildTree(List<T> dataList, Function<T, T> map, Predicate<T> filter) {
return buildTree(dataList, ROOT_NODE_IDS, map, filter);
}
public static <T extends TreeNodeBase> List<T> buildTree(List<T> dataList, List<Object> rootIds) {
return buildTree(dataList, rootIds,(data) -> data, (item) -> true);
}
public static <T extends TreeNodeBase> List<T> buildTree(List<T> dataList, List<Object> rootIds, Function<T, T> map) {
return buildTree(dataList, rootIds, map, (item) -> true);
}
public static <T extends TreeNodeBase> List<T> buildTree(List<T> dataList, List<Object> rootIds, Predicate<T> filter) {
return buildTree(dataList, rootIds, (data) -> data, filter);
}
public static <T extends TreeNodeBase> List<T> buildTree(List<T> dataList, List<Object> rootIds, Function<T, T> map, Predicate<T> filter) {
if(map==null){
map = (data)->data;
}
if(filter==null){
filter = (data)->true;
}
if (CollectionUtils.isEmpty(rootIds)) {
return Collections.emptyList();
}
Map<String, List<T>> nodeMap = dataList.stream()
.filter(filter)
.collect(Collectors.groupingBy(item -> rootIds.contains(item.getParentId()) ? PARENT_NAME : CHILDREN_NAME));
List<T> parent = nodeMap.getOrDefault(PARENT_NAME, Collections.emptyList());
List<T> children = nodeMap.getOrDefault(CHILDREN_NAME, Collections.emptyList());
if (parent.size() == 0) {
return Collections.emptyList();
}
List<Object> nextIds = new ArrayList<>(dataList.size());
List<T> collectParent = parent.stream().map(map).collect(Collectors.toList());
for (T parentItem : collectParent) {
if (nextIds.size() == children.size()) {
break;
}
children.stream()
.filter(childrenItem -> parentItem.getId().equals(childrenItem.getParentId()))
.forEach(childrenItem -> {
nextIds.add(childrenItem.getParentId());
parentItem.getChildren().add(childrenItem);
});
}
buildTree(children, nextIds, map, filter);
return parent;
}
}
三、测试
@Data
public class TreeNodeDemo implements TreeNodeBase<TreeNodeDemo> {
private Long id;
private String name;
private Long parentId;
public TreeNodeDemo(Long id, String name, Long parentId) {
this.id = id;
this.name = name;
this.parentId = parentId;
}
private List<TreeNodeDemo> children = new ArrayList<>();
public static void main(String[] args) {
List<TreeNodeDemo> testChildren = new ArrayList<>();
testChildren.add(new TreeNodeDemo(1L, "父元素", 0L));
testChildren.add(new TreeNodeDemo(2L, "子元素1", 1L));
testChildren.add(new TreeNodeDemo(3L, "子元素2", 1L));
testChildren.add(new TreeNodeDemo(4L, "子元素2的孙子元素", 3L));
System.out.println(JSON.toJSONString(TreeNodeUtil.buildTree(testChildren)));
}
}