java - 如何打破递归函数的多个实例调用?
问题描述
我正在创建一个递归函数,它将在图中找到两个节点之间的路径。只有在节点不重复时才会找到路径。如果一个节点连接到其他两个节点,则将创建递归函数的两个实例。如果两者都有正确的路径,则将设置最后找到的路径而不是第一个路径(行 this.nodePath = clonedNodePath;)。找到路径后,如何中断所有递归调用,而不仅仅是中断当前的递归调用实例?(我不想抛出异常)
private void process(String currentNodeId, List<String> currentNodePath) {
FlowNode currentFlowNode = modelInstance.getModelElementById(currentNodeId);
List<String> clonedNodePath = new ArrayList<>(currentNodePath);
if (currentFlowNode == null || clonedNodePath.contains(currentNodeId)) return;
clonedNodePath.add(currentNodeId);
if (currentNodeId.equals(finishNodeId)) {
this.nodePath = clonedNodePath;
return;
}
currentFlowNode.getOutgoing()
.stream()
.forEach(sequenceFlow -> process(sequenceFlow.getTarget().getId(), clonedNodePath));
}
解决方案
主要问题在于对传出egdes的迭代。
您选择使用 Java8 流来执行此操作,这不允许您提前中止(挑剔:您可以解决该“限制”,但这很笨拙)。
将其更改为经典for
循环,您的问题大部分都会消失。让您的process()
方法返回一个布尔成功指示,并在循环内,如果它给出 true,则在此process()
递归调用中返回 true。
或者更优雅:让process()
方法返回一个Optional<List<String>>
,如果失败则为空,如果成功则填充路径。然后你也摆脱了通过this.nodePath
. 并且 process() 方法最好命名为findPath()
.
PS 我知道使用流很流行,但在某些情况下它们根本不是合适的工具。
推荐阅读
- angular - Angular:将数据从材料对话框传递到未打开对话框的组件
- javascript - 在哪里放置我的代码以选择第一个选项
- rest - 使用 JpaRepository 和 RestResource 在一行中区分
- android - Colors.xml 文件中的错误“错误:prolog 中不允许内容。”
- node.js - NodeJs expressjs 结构
- c# - Rider 编写 Roslyn 分析器
- javascript - 停止 Rxjs 观察者的下一次执行?
- python - 多语言安装
- python - Python:删除元素的列表
- javascript - JavaScript 换色器无法正常工作