Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Returning min on a stream determined by object outside of Stream

I'm looking for a Comparator to write to put inside a min in a stream on a collection, let's just say it's a List<Node> . Normally I'd just compare the objects of the List against one another, but my issue is I have a <Node> which is outside of the collection, and I need to return the minimum value of the Nodes within the collection, as they are pitted against the parent node.

I have an object of Node

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

I compare the nodes in the collection against the parent node with an outside function:

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

And now I want to basically write a stream operation that returns the Node with the lowest value as it compares to its parent Node but that won't be in the set. Something like:

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

nodeList does not contain parent, and is a List<Node>

In the area containing the ??? is where I would send each N out for evaluation against its parent. So, if calling

distanceBetween(parent, n1) > distanceBetween(parent, n2) , it would result in n1 being returned . But I can't quite configure the function correctly. Any ideas? Thank you!

like image 834
NateH06 Avatar asked Dec 18 '25 00:12

NateH06


2 Answers

You can use Comparator.comparingInt to make the comparator:

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

It is customary to use static import of comparingInt, so you stream expression becomes:

return nodeList.stream()
          .min(comparingInt(n -> distanceBetween(parent, n));
          .orElse(parent); 
like image 166
Misha Avatar answered Dec 20 '25 17:12

Misha


The parent node (the one which is not contained in the list) seems to be fixed. This establishes an origin from which to measure the distance to the nodes of the list. If I understand correctly, you want to return the node of the list which is nearest this parent node.

For this, you'd need to get the distances of nodes n1 and n2 to the parent node, and compare these actual distances each other. You should return a negative value if n1 is closer to the parent node than n2, 0 if both n1 and n2 are equally far away from the parent node, and a positive value if n2 is closer to the parent node than n1. Here is a method with that logic:

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
}

And here's the comparator that uses the method above:

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

Note: if you wanted exactly the opposite (to return the node that is farthest the parent node instead of the one that is nearest the parent node), you should use max instead of min:

return nodeList.stream()
    .max(this::compareDistances)
    .getOrElse(parent); 
like image 27
fps Avatar answered Dec 20 '25 16:12

fps



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!