递归方法的Java8实现
将lambdas用于递归方法的正确方法是什么?我一直在尝试为图形编写一个深度优先搜索递归函数。我尝试过实现Lambda版本,但不确定我的实现是否是在递归函数中使用它的正确方法 代码大纲:递归方法的Java8实现,java,recursion,lambda,java-8,Java,Recursion,Lambda,Java 8,将lambdas用于递归方法的正确方法是什么?我一直在尝试为图形编写一个深度优先搜索递归函数。我尝试过实现Lambda版本,但不确定我的实现是否是在递归函数中使用它的正确方法 代码大纲: private void depthFirstSearchJava8(final Graph graph, final int sourceVertex){ count++; marked[sourceVertex]= true; StreamSupport.stream(graph.g
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);
}
});
}
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作为另一个函数的参数传递时。如果您的lambda占用多行代码,您应该重新考虑使用它的想法。仅仅因为lambda存在,并不意味着您必须在任何地方使用它们 您正在一个iterable上循环,没有过滤、映射或转换任何东西(这是lambdas的典型用例)
for
循环在一行程序中实现您想要的功能。因此,此处不应使用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()
方法来终止流。只需注意:如果需要在lambda中放入多行,那么在图中使用lambda可能设计得不好。getAllVerticesConnectedTo(sourceVertex)
返回Iterable
,这个StreamSupport.stream(blahblah)
有什么意义Iterable
界面已经有了forEach
@TagirValeev:感谢您宝贵的回复。仍在学习lambdas的过程中,因此无法发现它。条件情况不应该被视为过滤吗?是的,if
可以被视为过滤。当我写答案的时候,我没有看到这一点。但即便如此,没有lambdas,代码看起来仍然简单。