2016-03-13 3 views
-1

Каков правильный способ использования lambdas для рекурсивного метода? Я пытаюсь написать рекурсивную функцию поиска глубины для диаграммы . Я пробовал реализовать Lambda-версию, но не уверен, что моя реализация - правильный способ ее использования в рекурсивной функции.реализация Java 8 для рекурсивного метода

Структура кода:

а) старинке

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

б) Java 8 Лямбда путь:

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

Я попытался написать лямбда-версия, как указано выше, но не могла понять преимущества он обеспечивает по сравнению с традиционным способом.

Благодаря

+1

только для примечания: если вам нужно положить в свою лямбду более одной строки, это, вероятно, плохой дизайн для использования лямбда – ByeBye

+2

Если ваш 'graph.getAllVerticesConnectedTo (sourceVertex)' возвращает 'Iterable', то в чем смысл этого' StreamSupport.stream (blahblah) '? Интерфейс 'Iterable' уже имеет' forEach'. –

+0

@TagirValeev: Спасибо за ваш ценный ответ. Все еще в процессе изучения лямбда, так что он не смог его обнаружить. –

ответ

1

Просто потому, что существуют лямбда, это не значит, что вы должны использовать их повсюду.

Вы перебираете итерацию, без фильтрации или сопоставления или преобразования чего-либо (что является типичным случаем использования для лямбда).

Цикл for делает то, что вы хотите, в однострочном пространстве. Поэтому лямбда не следует использовать здесь.

+1

Не следует ли рассматривать условный случай как фильтрацию? –

+0

Да, 'if' можно рассматривать как фильтрацию. Я не видел этого, когда писал ответ. Но даже тогда код по-прежнему выглядит проще без лямбда. –

0

Это потому, что нет никаких преимуществ, по крайней мере, не в этом случае. Lambdas полезны, когда вы хотите создать небольшую функцию, которая будет использоваться только в одном месте в программе, например. при прохождении лямбды в качестве аргумента для другой функции. Если ваша лямбда занимает более одной строки кода, вы должны пересмотреть идею ее использования.

0

Вы можете переписать метод 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(), чтобы получить поток связных вершин, в то время как во втором, я ve использовали метод Arrays.stream(). Затем в обоих решениях я сначала использовал filter(), чтобы сохранить только не отмеченные вершины и peek(), чтобы изменить массив edgeTo. Наконец, forEach() используется для завершения потока путем вызова метода depthFirstSearchJava8() рекурсивно.

Смежные вопросы