2017-03-05 22 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); 
相关问题