Java树形结构案例怎么构建

wen java案例 26

本文目录导读:

Java树形结构案例怎么构建

  1. 基础节点定义
  2. 核心构建方法
  3. 实际应用示例
  4. 增强版节点(支持更多功能)
  5. 完整工具类
  6. Spring Boot项目中的使用

构建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);
    }
}
  1. 数据结构:节点需要包含idparentIdchildren列表
  2. 构建方式
    • 递归方式:逻辑清晰,但大数据量时性能较差
    • HashMap方式:性能更好,推荐使用
  3. 空值处理:根节点的parentId通常为null或0
  4. 排序支持:可以在构建后按sort字段排序
  5. 扩展性:节点可以包含自定义属性和方法

选择哪种方式取决于你的具体需求,对于大多数业务场景,使用HashMap优化的方式就足够了。

抱歉,评论功能暂时关闭!