《《《用java递归查询树节点返回List,并可以根据name查询节点
来自豆包
一、核心逻辑说明
二、完整代码实现
1. 树节点实体类(TreeNode)
import java.util.ArrayList; import java.util.List; /** * 树节点基础实体 */ public class TreeNode { // 节点唯一标识 private Long id; // 父节点ID private Long parentId; // 节点名称(用于查询) private String name; // 子节点列表 private List<TreeNode> children; // 构造器:初始化子节点列表,避免空指针 public TreeNode(Long id, Long parentId, String name) { this.id = id; this.parentId = parentId; this.name = name; this.children = new ArrayList<>(); } // Getter & Setter public Long getId() { return id; } public void setId(Long id) { this.id = id; } public Long getParentId() { return parentId; } public void setParentId(Long parentId) { this.parentId = parentId; } public String getName() { return name; } public void setName(String name) { this.name = name; } public List<TreeNode> getChildren() { return children; } public void setChildren(List<TreeNode> children) { this.children = children; } // 重写toString,方便打印结果 @Override public String toString() { return "TreeNode{" + "id=" + id + ", parentId=" + parentId + ", name='" + name + '\'' + '}'; } }
2. 树节点递归工具类(TreeUtils)
import java.util.ArrayList; import java.util.List; /** * 树节点递归遍历/查询工具类 */ public class TreeUtils { // ==================== 基础递归遍历:返回全量节点List ==================== /** * 递归先序遍历(根→子),返回所有节点的扁平化List * @param rootNode 起始节点(根节点/任意子节点) * @return 全量节点列表 */ public static List<TreeNode> listAllNodes(TreeNode rootNode) { List<TreeNode> result = new ArrayList<>(); traversePreOrder(rootNode, result); return result; } /** * 私有递归方法:先序遍历核心逻辑 */ private static void traversePreOrder(TreeNode currentNode, List<TreeNode> result) { if (currentNode == null) { return; } // 先加入当前节点 result.add(currentNode); // 递归遍历子节点 List<TreeNode> children = currentNode.getChildren(); if (children != null && !children.isEmpty()) { for (TreeNode child : children) { traversePreOrder(child, result); } } } // ==================== 按名称查询节点:精确/模糊 ==================== /** * 按名称精确匹配查询节点 * @param rootNode 起始节点 * @param targetName 目标名称(trim后完全一致) * @return 匹配的节点列表 */ public static List<TreeNode> searchByExactName(TreeNode rootNode, String targetName) { List<TreeNode> result = new ArrayList<>(); searchByName(rootNode, targetName, true, result); return result; } /** * 按名称模糊匹配查询节点(忽略大小写,包含目标字符串) * @param rootNode 起始节点 * @param targetName 目标名称 * @return 匹配的节点列表 */ public static List<TreeNode> searchByFuzzyName(TreeNode rootNode, String targetName) { List<TreeNode> result = new ArrayList<>(); searchByName(rootNode, targetName, false, result); return result; } /** * 私有递归方法:名称匹配核心逻辑 * @param currentNode 当前遍历节点 * @param targetName 目标名称 * @param isExact 是否精确匹配 * @param result 结果列表 */ private static void searchByName(TreeNode currentNode, String targetName, boolean isExact, List<TreeNode> result) { // 空值防护:节点为空/目标名称为空,直接返回 if (currentNode == null || targetName == null || targetName.trim().isEmpty()) { return; } String nodeName = currentNode.getName(); boolean match = false; if (nodeName != null) { String target = targetName.trim(); String nodeNameTrim = nodeName.trim(); if (isExact) { // 精确匹配:trim后完全相等 match = nodeNameTrim.equals(target); } else { // 模糊匹配:忽略大小写,包含目标字符串 match = nodeNameTrim.toLowerCase().contains(target.toLowerCase()); } } // 匹配则加入结果 if (match) { result.add(currentNode); } // 递归遍历子节点 List<TreeNode> children = currentNode.getChildren(); if (children != null && !children.isEmpty()) { for (TreeNode child : children) { searchByName(child, targetName, isExact, result); } } } }
3. 测试类(TreeNodeTest)
public class TreeNodeTest { public static void main(String[] args) { // 1. 构建测试树形结构 TreeNode root = new TreeNode(1L, 0L, "系统管理"); TreeNode menu1 = new TreeNode(2L, 1L, "用户管理"); TreeNode menu2 = new TreeNode(3L, 1L, "角色管理"); TreeNode menu11 = new TreeNode(4L, 2L, "用户列表"); TreeNode menu12 = new TreeNode(5L, 2L, "新增用户"); TreeNode menu21 = new TreeNode(6L, 3L, "角色列表"); TreeNode menu22 = new TreeNode(7L, 3L, "用户角色分配"); // 组装子节点关系 menu1.getChildren().add(menu11); menu1.getChildren().add(menu12); menu2.getChildren().add(menu21); menu2.getChildren().add(menu22); root.getChildren().add(menu1); root.getChildren().add(menu2); // 2. 测试1:递归遍历所有节点 System.out.println("===== 递归遍历所有节点 ====="); List<TreeNode> allNodes = TreeUtils.listAllNodes(root); allNodes.forEach(System.out::println); // 3. 测试2:精确匹配名称"用户列表" System.out.println("\n===== 精确匹配「用户列表」 ====="); List<TreeNode> exactMatch = TreeUtils.searchByExactName(root, "用户列表"); printResult(exactMatch); // 4. 测试3:模糊匹配名称"用户"(忽略大小写) System.out.println("\n===== 模糊匹配「用户」 ====="); List<TreeNode> fuzzyMatch = TreeUtils.searchByFuzzyName(root, "用户"); printResult(fuzzyMatch); // 5. 测试4:仅查询"用户管理"子树下的"新增"节点 System.out.println("\n===== 仅查询「用户管理」子树下模糊匹配「新增」 ====="); List<TreeNode> partialMatch = TreeUtils.searchByFuzzyName(menu1, "新增"); printResult(partialMatch); // 6. 测试5:匹配不存在的名称 System.out.println("\n===== 模糊匹配「菜单」 ====="); List<TreeNode> noMatch = TreeUtils.searchByFuzzyName(root, "菜单"); printResult(noMatch); } // 辅助打印方法:统一处理空列表 private static void printResult(List<TreeNode> nodes) { if (nodes.isEmpty()) { System.out.println("无匹配节点"); return; } nodes.forEach(System.out::println); } }
三、输出结果
===== 递归遍历所有节点 ===== TreeNode{id=1, parentId=0, name='系统管理'} TreeNode{id=2, parentId=1, name='用户管理'} TreeNode{id=4, parentId=2, name='用户列表'} TreeNode{id=5, parentId=2, name='新增用户'} TreeNode{id=3, parentId=1, name='角色管理'} TreeNode{id=6, parentId=3, name='角色列表'} TreeNode{id=7, parentId=3, name='用户角色分配'} ===== 精确匹配「用户列表」 ===== TreeNode{id=4, parentId=2, name='用户列表'} ===== 模糊匹配「用户」 ===== TreeNode{id=2, parentId=1, name='用户管理'} TreeNode{id=4, parentId=2, name='用户列表'} TreeNode{id=5, parentId=2, name='新增用户'} TreeNode{id=7, parentId=3, name='用户角色分配'} ===== 仅查询「用户管理」子树下模糊匹配「新增」 ===== TreeNode{id=5, parentId=2, name='新增用户'} ===== 模糊匹配「菜单」 ===== 无匹配节点
四、关键特性说明
五、迭代版扩展(防栈溢出)
/** * 迭代版:模糊查询名称(防栈溢出) */ public static List<TreeNode> searchByFuzzyNameIteration(TreeNode rootNode, String targetName) { List<TreeNode> result = new ArrayList<>(); if (rootNode == null || targetName == null || targetName.trim().isEmpty()) { return result; } String target = targetName.trim().toLowerCase(); Deque<TreeNode> stack = new LinkedList<>(); stack.push(rootNode); while (!stack.isEmpty()) { TreeNode node = stack.pop(); // 匹配逻辑 String nodeName = node.getName(); if (nodeName != null && nodeName.trim().toLowerCase().contains(target)) { result.add(node); } // 子节点逆序入栈(保证遍历顺序和递归一致) List<TreeNode> children = node.getChildren(); if (children != null && !children.isEmpty()) { for (int i = children.size() - 1; i >= 0; i--) { stack.push(children.get(i)); } } } return result; }
每天多努力一点,你将会变得更好。

浙公网安备 33010602011771号