如何解决用Java递归遍历继承树
我需要获取一个给定的记录并用其所有子记录的标识符填充一个列表(即原始项目的所有子记录、子项的所有子记录、孙子的所有子记录等)我目前有一种方法可以产生我想要的东西,但它不是最容易阅读的方法,它使用迭代而不是递归。我想知道是否有更简洁的方法来实现我想要的,可能使用递归调用,但主要目的是使代码更易于阅读。目前实现如下
public List<String> getAllChildRecords(targetRecord) {
final List<String> allChildRecordIds = new ArrayList<>();
final List<String> recordIdsForQuery = new ArrayList<>();
final List<String> queryResults = new ArrayList<>();
recordIdsForQuery.add(targetRecord);
while (!recordIdsForQuery .isEmpty()) {
for (final String queryParentId : recordIdsForQuery ) {
queryResults.addAll(
[dbaccessLayerClass].[getChildRecordIds](queryParentId));
}
allChildRecordIds .addAll(queryResults);
recordIdsForQuery .clear();
recordIdsForQuery .addAll(queryResults);
queryResults.clear();
}
return allChildRecordIds
}
解决方法
递归通常不是正确的答案,尤其是在 Java 中 - 例如,它往往很慢,并且会产生复杂的堆栈跟踪。因此,“仅重写为递归”不是最佳答案,因此,如果您担心可读性,这也不是最佳改进。
通常的技巧是使用队列。另外,不要将事情声明为最终的“为了可读性” - 您正在向此代码添加大量噪音。如果您坚持将“更改本地人”减少到最低限度以提高可读性,请将您的 IDE 配置为以高度可见的方式呈现对本地人的写入,不要通过在各处添加一堆嘈杂的关键字来弄乱您的代码。
var out = new ArrayList<String>();
var queue = new ArrayDeque<String>();
queue.add(targetRecord);
while (!queue.isEmpty()) {
String id = queue.pop();
var childIds = DbAccessLayerClass.getChildRecordIds(id));
out.addAll(childIds);
queue.addAll(childIds);
}
return out;
如果您害怕循环或重复(例如,其中 1 个项目可以是多个单独条目的子项),请将您的 out
改为 (Linked)HashSet
,并添加 {{1 }} 紧跟在 childIds.removeAll(out);
之后。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。