0

What is the correct way of using lambdas for a recursive method? I have been trying to write a depth-first-search recursive function for a Graph. I have tried implementing the Lambda version, but not sure if my implementation is the correct way of using it in a recursive function.

Outline of the code:

a) Old fashioned way

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 way:

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);
                }
            });
}

I have tried to write a lambda version as above but could not figure out the advantage it is providing as compared to the traditional way.

Thanks

3
  • 1
    just for note: if you need to put in your lambda more than one line, it is probably poor design for lambda usage Commented Mar 13, 2016 at 11:44
  • 2
    If your graph.getAllVerticesConnectedTo(sourceVertex) returns Iterable, what's the point of this StreamSupport.stream(blahblah)? Iterable interface already has forEach. Commented Mar 13, 2016 at 12:05
  • @TagirValeev: Thanks for your valuable response. Still in the process of learning lambdas, so was not able to spot it. Commented Mar 13, 2016 at 12:26

3 Answers 3

1

Just because lambdas exist, this doesn't mean you have to use them everywhere.

You are looping over an iterable, without filtering or mapping or transforming anything (which are the typical use cases for lambdas).

The for loop does what you want in a one-liner. Therefore, lambdas should not be used here.

Sign up to request clarification or add additional context in comments.

2 Comments

Should not the conditional case be considered as filtering?
Yes, the if can be considered filtering. I hadn’t seen that when I wrote the answer. But even then, the code still looks simpler without lambdas.
0

That's because there is no advantage, at least not in this case. Lambdas are useful when you want to create a small function to be used in just one place in the program, e.g. when passing the lambda as an argument for another function. If your lambda takes more than one line of code, you should reconsider the idea of using it.

Comments

0

You could rewrite your depthFirstSearch method as follows:

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));
}

This code assumes getAllVerticesConnectedTo() method returns a collection of integers. If it returns an array of integers instead, then use the following code:

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));
}

In the first solution, I've used the Collection.stream() method to get a stream of connected vertices, while in the second one, I've used the Arrays.stream() method. Then, in both solutions, I've first used filter() to keep only non marked vertices and peek() to modify the edgeTo array. Finally, forEach() is used to terminate the stream by invoking depthFirstSearchJava8() method recursively.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.