2017-03-05 59 views
3

我正在尋找Comparator來寫入minstream集合中,我們只是假設它是List<Node>。通常我只是比較列表中的對象,但我的問題是我有一個<Node>這是在集合之外,我需要返回集合中的節點的最小值,因爲它們是對齊的父節點。返回分辨率由流對象確定的流

我有Node

public class Node { 
    private int cost; 
    private int location; 
    public int getCost() { return cost } 
} 

對象我對與外部功能的父節點集合中的比較節點:

public int distanceBetween(Node parent, Node child) { ... }

現在我想基本上寫流操作返回節點的最低值,因爲它與其父母Node相比較,但不在集合中。喜歡的東西:

private Node returnOpenNodeWithLowestFCost(Node parent) { 
     return nodeList.stream() 
        .min((n1 , n2) -> ???); 
        .getOrElse(parent); 
    } 

nodeList不含parent,並且是List<Node>

在包含區域???是我將每個N發送給其父母進行評估的地方。所以,如果調用

distanceBetween(parent, n1) > distanceBetween(parent, n2),它會導致返回n1。但我無法正確配置該功能。有任何想法嗎?謝謝!

回答

3

父節點(不包含在列表中的那個節點)似乎是固定的。這建立了一個來源來衡量到列表節點的距離。如果我理解正確,你想返回最接近這個父節點的列表的節點。

爲此,您需要獲取節點n1n2到父節點的距離,並將這些實際距離相互比較。你應該返回一個負值,如果n1n2接近父節點,0如果兩個n1n2同樣遠離父節點,如果n2正值更接近比n1父節點。下面是與邏輯的方法:

private int compareDistances(Node n1, Node n2) { 
    int distance1 = this.distanceBetween(parent, n1); 
    int distance2 = this.distanceBetween(parent, n2); 

    return distance2 - distance1; // negative if n1 closer than n2 
} 

這裏是一個使用上面的方法比較:

return nodeList.stream() 
    .min(this::compareDistances) 
    .getOrElse(parent); 

注意:如果你想完全相反(返回是最遠的父節點節點,而不是一個最接近父節點),你應該使用max而不是min

return nodeList.stream() 
    .max(this::compareDistances) 
    .getOrElse(parent); 
+0

謝謝。到目前爲止都是正確的,但我選擇你的答案的清晰度。後續問題,如果我的'nodeList'只包含1個項目會發生什麼,如果期望始終比較'nodeList'中的至少2個不同的值,'min()'方法會有問題嗎? – NateH06

+1

@ NateH06沒有問題,你只提供邏輯來比較兩個元素,但你的代碼實際上並沒有執行任何比較。你提到的特殊情況是在那裏正確處理的,我想通過我認爲是在流實現類中的代碼。 –

5

您可以使用Comparator.comparingInt作比較:

Comparator<Node> byDistFromParent = Comparator.comparingInt(n -> distanceBetween(parent, n)); 

這是習慣使用的comparingInt靜態導入,讓你流式變爲:

return nodeList.stream() 
      .min(comparingInt(n -> distanceBetween(parent, n)); 
      .orElse(parent); 
相關問題