Reputation: 3594
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!
Upvotes: 3
Views: 156
Reputation: 28153
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);
Upvotes: 5
Reputation: 34460
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);
Upvotes: 3