我一次又一次地遇到这个问题,我有一个非常简单的解决方案,但我想知道还有哪些其他算法更干净,更可维护。我的特定用例涉及处理数据管道,在该管道中,我将多次收到此结构,并在完成后将其处理。我将只需要迭代一次此结构。
假设您有一个具有父子关系的树结构;这是一个无边界的一对多关系。
public class Node {
private String name;
private Boolean resource;
private Node parent;
private List<Node> children;
// getters and setters...
}
可以说,我想从根节点开始递归搜索此结构,但建立该结构中所有节点的索引所产生的开销远远超过其价值。我可能会这样写:
private static Node getNodeByName(Node node, String name) {
if (node.getName().equals(name)) {
return node;
} else if (!node.getChildren().isEmpty()) {
for (Node node : node.getChildren()) {
Node childNode;
if ((childNode = getNodeByName(node, name)) != null) {
return childNode;
}
}
}
return null;
}
让我们更改需求。现在,我们要收集符合特定条件的
List
的Node
。private static List<Node> getResourceNodes(Node node) {
List<Node> matchedNodes = new ArrayList<>();
SomeClass.getResourceNodes(node, matchedNodes);
return matchedNodes;
}
private static void getResourceNodes(Node node, List<Node> matchedNodes) {
if (node.isResource())) {
matchedNodes.add(node);
}
if (!node.getChildren().isEmpty()) {
for (Node node : node.getChildren()) {
getResourceNodes(node, matchedNodes);
}
}
}
我直接在这里写的。可能存在一两个语法错误。我想知道还可以采用其他什么方式,也许更易于维护。这就是我一直接触链接节点的方式,现在我很想知道是否有更好的方法。
最佳答案
如果您正在寻找一种更清洁,更可维护的算法,请不要通过方法传递列表(向下构建列表)。而是通过返回列表来向上构建列表。
private static List<Node> getResourceNodes(Node node) {
List<Node> matchedNodes = new ArrayList<>();
if (node.isResource()) matchedNodes.add(node);
for (Node child : node.getChildren()) {
matchedNodes.addAll(getResourceNodes(child);
}
return matchedNodes;
}