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