递归方法的Java8实现

递归方法的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

将lambdas用于递归方法的正确方法是什么?我一直在尝试为图形编写一个深度优先搜索递归函数。我尝试过实现Lambda版本,但不确定我的实现是否是在递归函数中使用它的正确方法

代码大纲:

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,代码看起来仍然简单。