[英]Java 8 implementation for recursive method
将 lambda 用于递归方法的正确方法是什么? 我一直在尝试为Graph编写一个深度优先搜索递归函数。 我曾尝试实现 Lambda 版本,但不确定我的实现是否是在递归函数中使用它的正确方法。
代码概要:
a) 老式的方式
private void depthFirstSearch(final Graph graph, final int sourceVertex){
count++;
marked[sourceVertex]= true;
for(int vertex:graph.getAllVerticesConnectedTo(sourceVertex)){
if(marked[vertex]!=true){
edgeTo[vertex]=sourceVertex;
depthFirstSearch(graph,vertex);
}
}
}
b) Java 8 Lambdas 方式:
private void depthFirstSearchJava8(final Graph graph, final int sourceVertex){
count++;
marked[sourceVertex]= true;
StreamSupport.stream(graph.getAllVerticesConnectedTo(sourceVertex).spliterator(),false)
.forEach(vertex -> {
if(marked[vertex]!=true){
edgeTo[vertex]=sourceVertex;
depthFirstSearchJava8(graph,sourceVertex);
}
});
}
我曾尝试编写如上所述的 lambda 版本,但无法弄清楚与传统方式相比它提供的优势。
谢谢
仅仅因为 lambda 存在,这并不意味着您必须在任何地方使用它们。
您正在遍历一个可迭代对象,而无需过滤、映射或转换任何内容(这是 lambda 的典型用例)。
for
循环在单行中执行您想要的操作。 因此,此处不应使用 lambda。
那是因为没有优势,至少在这种情况下没有优势。 当您想创建一个仅在程序中的一个地方使用的小函数时,Lambda 很有用,例如,当将 lambda 作为另一个函数的参数传递时。 如果您的 lambda 超过一行代码,您应该重新考虑使用它的想法。
您可以按如下方式重写depthFirstSearch
方法:
private void depthFirstSearchJava8(Graph graph, int sourceVertex){
count++;
marked[sourceVertex] = true;
graph.getAllVerticesConnectedTo(sourceVertex).stream()
.filter(vertex -> !marked[vertex])
.peek(vertex -> edgeTo[vertex] = sourceVertex)
.forEach(vertex -> depthFirstSearchJava8(graph, vertex));
}
此代码假定getAllVerticesConnectedTo()
方法返回整数集合。 如果它返回一个整数数组,则使用以下代码:
private void depthFirstSearchJava8(Graph graph, int sourceVertex){
count++;
marked[sourceVertex] = true;
Arrays.stream(graph.getAllVerticesConnectedTo(sourceVertex))
.filter(vertex -> !marked[vertex])
.peek(vertex -> edgeTo[vertex] = sourceVertex)
.forEach(vertex -> depthFirstSearchJava8(graph, vertex));
}
在第一个解决方案中,我使用了Collection.stream()
方法来获取连接顶点的流,而在第二个解决方案中,我使用了Arrays.stream()
方法。 然后,在这两种解决方案中,我首先使用filter()
仅保留未标记的顶点,并使用peek()
修改edgeTo
数组。 最后, forEach()
用于通过递归调用depthFirstSearchJava8()
方法来终止流。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.