本文目录导读:

构建Java树形结构通常用于表示层级关系数据,如组织架构、菜单、分类等,以下是几种常见且实用的构建方式:
基础节点定义
// 通用树节点
public class TreeNode {
private Long id;
private Long parentId;
private String name;
private List<TreeNode> children = new ArrayList<>();
// 构造方法
public TreeNode(Long id, Long parentId, String name) {
this.id = id;
this.parentId = parentId;
this.name = name;
}
// Getter/Setter...
}
核心构建方法
import java.util.*;
import java.util.stream.Collectors;
public class TreeBuilder {
/**
* 构建树形结构(递归方式)
*/
public static List<TreeNode> buildTree(List<TreeNode> nodes) {
// 1. 获取所有根节点(parentId为null或0)
List<TreeNode> roots = nodes.stream()
.filter(node -> node.getParentId() == null || node.getParentId() == 0)
.collect(Collectors.toList());
// 2. 为每个根节点构建子节点
for (TreeNode root : roots) {
buildChildren(root, nodes);
}
return roots;
}
/**
* 递归构建子节点
*/
private static void buildChildren(TreeNode parent, List<TreeNode> nodes) {
List<TreeNode> children = nodes.stream()
.filter(node -> Objects.equals(node.getParentId(), parent.getId()))
.collect(Collectors.toList());
for (TreeNode child : children) {
buildChildren(child, nodes);
}
parent.setChildren(children);
}
/**
* 使用HashMap优化(推荐,性能更好)
*/
public static List<TreeNode> buildTreeFast(List<TreeNode> nodes) {
// 创建ID->Node的映射
Map<Long, TreeNode> nodeMap = new HashMap<>();
List<TreeNode> roots = new ArrayList<>();
// 将所有节点放入Map
for (TreeNode node : nodes) {
nodeMap.put(node.getId(), node);
}
// 构建父子关系
for (TreeNode node : nodes) {
if (node.getParentId() != null && node.getParentId() != 0) {
TreeNode parent = nodeMap.get(node.getParentId());
if (parent != null) {
parent.getChildren().add(node);
}
} else {
roots.add(node);
}
}
return roots;
}
}
实际应用示例
public class TreeDemo {
public static void main(String[] args) {
// 模拟数据库查询到的扁平数据
List<TreeNode> flatData = Arrays.asList(
new TreeNode(1L, 0L, "根节点"),
new TreeNode(2L, 1L, "节点A"),
new TreeNode(3L, 1L, "节点B"),
new TreeNode(4L, 2L, "节点A-1"),
new TreeNode(5L, 2L, "节点A-2"),
new TreeNode(6L, 3L, "节点B-1")
);
// 构建树
List<TreeNode> tree = TreeBuilder.buildTreeFast(flatData);
// 打印树(JSON格式)
System.out.println(new Gson().toJson(tree));
}
}
增强版节点(支持更多功能)
public class EnhancedTreeNode {
private Long id;
private Long parentId;
private String name;
private Boolean disabled; // 是否禁用
private Boolean checked; // 是否选中(用于树形选择框)
private Integer sort; // 排序字段
private List<EnhancedTreeNode> children = new ArrayList<>();
private Map<String, Object> extra = new HashMap<>(); // 扩展属性
// 添加辅助方法
public void addChild(EnhancedTreeNode child) {
this.children.add(child);
}
public boolean isLeaf() {
return children == null || children.isEmpty();
}
// Getter/Setter...
}
完整工具类
public class TreeUtil {
/**
* 通用树构建方法(支持泛型)
*/
public static <T extends TreeNode> List<T> buildTree(
List<T> nodes,
Function<T, Long> getId,
Function<T, Long> getParentId,
Function<T, List<T>> getChildren,
BiConsumer<T, List<T>> setChildren) {
Map<Long, T> nodeMap = nodes.stream()
.collect(Collectors.toMap(getId, node -> node));
List<T> roots = new ArrayList<>();
for (T node : nodes) {
Long parentId = getParentId.apply(node);
if (parentId == null || parentId == 0) {
roots.add(node);
} else {
T parent = nodeMap.get(parentId);
if (parent != null) {
List<T> children = getChildren.apply(parent);
if (children == null) {
children = new ArrayList<>();
setChildren.accept(parent, children);
}
children.add(node);
}
}
}
return roots;
}
}
Spring Boot项目中的使用
@Service
public class MenuServiceImpl implements MenuService {
@Autowired
private MenuMapper menuMapper;
@Override
public List<MenuVO> getMenuTree() {
// 从数据库查询所有菜单
List<Menu> menus = menuMapper.selectList(null);
// 转换为树节点
List<TreeNode> nodes = menus.stream()
.map(menu -> new TreeNode(menu.getId(), menu.getParentId(), menu.getName()))
.collect(Collectors.toList());
// 构建树
return TreeBuilder.buildTreeFast(nodes);
}
}
- 数据结构:节点需要包含
id、parentId和children列表 - 构建方式:
- 递归方式:逻辑清晰,但大数据量时性能较差
- HashMap方式:性能更好,推荐使用
- 空值处理:根节点的
parentId通常为null或0 - 排序支持:可以在构建后按
sort字段排序 - 扩展性:节点可以包含自定义属性和方法
选择哪种方式取决于你的具体需求,对于大多数业务场景,使用HashMap优化的方式就足够了。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播