如何用纯Java递归获取Message对象的所有子节点并存入List?
递归获取所有嵌套Message子节点的实现方案
当然可以实现,下面提供两种常用的实现方式,适配不同场景需求:
1. 递归实现(简洁直观)
这种方式代码简洁,适合嵌套层级不深的场景,可以直接在Message类内部实现,或者写独立工具方法:
类内方法实现
import java.util.ArrayList; import java.util.List; class Message { private int id; private String status; private List<Message> children; // 省略getters、setters // 收集当前节点的所有子节点(含深层嵌套子节点) public List<Message> getAllChildren() { List<Message> allChildren = new ArrayList<>(); traverseAndCollect(this, allChildren); allChildren.remove(this); // 可选:移除当前节点,只保留子节点层级 return allChildren; } private void traverseAndCollect(Message node, List<Message> result) { result.add(node); // 判空避免空指针 if (node.getChildren() != null && !node.getChildren().isEmpty()) { for (Message child : node.getChildren()) { traverseAndCollect(child, result); } } } }
独立工具类实现
import java.util.ArrayList; import java.util.List; public class MessageUtils { public static List<Message> collectAllChildren(Message root) { List<Message> allChildren = new ArrayList<>(); if (root == null) return allChildren; collectRecursive(root, allChildren); allChildren.remove(root); // 移除根节点,仅保留子节点 return allChildren; } private static void collectRecursive(Message node, List<Message> result) { result.add(node); if (node.getChildren() != null) { for (Message child : node.getChildren()) { collectRecursive(child, result); } } } }
2. 迭代实现(避免栈溢出)
如果Message嵌套层级极深(比如上万层),递归会触发StackOverflowError,这时用迭代方式更安全,下面提供两种遍历方式:
深度优先遍历(栈实现)
import java.util.ArrayList; import java.util.List; import java.util.Stack; public class MessageUtils { public static List<Message> collectAllChildrenIterative(Message root) { List<Message> allChildren = new ArrayList<>(); if (root == null) return allChildren; Stack<Message> stack = new Stack<>(); stack.push(root); while (!stack.isEmpty()) { Message current = stack.pop(); allChildren.add(current); // 栈是后进先出,反向遍历子节点保证顺序和递归一致 if (current.getChildren() != null) { for (int i = current.getChildren().size() - 1; i >= 0; i--) { stack.push(current.getChildren().get(i)); } } } allChildren.remove(root); return allChildren; } }
广度优先遍历(队列实现)
import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Queue; public class MessageUtils { public static List<Message> collectAllChildrenBFS(Message root) { List<Message> allChildren = new ArrayList<>(); if (root == null) return allChildren; Queue<Message> queue = new LinkedList<>(); queue.offer(root); while (!queue.isEmpty()) { Message current = queue.poll(); allChildren.add(current); if (current.getChildren() != null) { queue.addAll(current.getChildren()); } } allChildren.remove(root); return allChildren; } }
注意事项
- 如果不需要包含根节点,可直接在遍历逻辑中跳过根节点的添加,或者调用
allChildren.remove(root)。 - 必须对
children列表判空,避免空指针异常。 - 生产环境若嵌套层级不确定,优先选择迭代实现,避免栈溢出风险。
内容的提问来源于stack exchange,提问作者AntonBoarf
相关产品推荐
相关产品推荐

