簡體   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