繁体   English   中英

递归方法的 Java 8 实现

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM