I'm having a few complications with the Java Comparator
. So I have a parent node that has a list of children. I want to sort those children, seems pretty simple on the face of it, however when the Comparator
does the sorting it only checks certain objects against certain objects, then I suppose it infers the positions of objects, as to say if a
is before d
, f
is after d
, b
is before d
which means b
is before f
.
Below is an example of my current setup. I have a parent node a
with 4 children nodes b
, e
, l
, g
. When I sort these children, I would expect the order to be b
, g
, l
, e
, so sorting by alphabet and always making sure a parent node comes first.
(Excuse the shoddy drawing)
Very simple, I have a Node
class, it contains an ID, so it's letter and then a list of children.
public class Node {
private char id;
private Node parent;
private List<Node> children = new ArrayList<>();
public Node(char id) {
this.id = id;
}
public void addChild(Node child) {
this.children.add(child);
}
public List<Node> getChildren() {
return children;
}
public char getId() {
return id;
}
public void setParent(Node parent) {
this.parent = parent;
}
public Node getParent() {
return parent;
}
@Override
public int hashCode() {
return Objects.hash(id);
}
@Override
public boolean equals(Object obj) {
return ((Node) obj).getId() == this.id;
}
}
I then have the NodeComparator
class which first checks if the nodes are your children and then if they are you go first, vice versa, then orders by alphabet.
@Override
public int compare(Node o1, Node o2) {
if (o1.getChildren().contains(o2)) {
return -1;
}
if (o2.getChildren().contains(o1)) {
return 1;
}
String alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int firstNodeIndex = -10;
int secondNodeIndex = -10;
for (int i = 0; i < alphabet.length(); i++) {
if (alphabet.charAt(i) == o1.getId()) {
firstNodeIndex = i;
}
if (alphabet.charAt(i) == o2.getId()) {
secondNodeIndex = i;
}
}
if (firstNodeIndex > secondNodeIndex) {
return 1;
} else if (firstNodeIndex == secondNodeIndex) {
return 0;
}else {
return -1;
}
}
}
The issue is that when the sorting is done it checks:
E against B
G against E
L against G
So it never check L against E so it has no way of knowing that should come first.
Your ordering violates Comparator
's contract:
The implementor must also ensure that the relation is transitive: ((compare(x, y)>0) && (compare(y, z)>0)) implies compare(x, z)>0.
compare('G','E') > 0 // since 'G' comes after 'E' in the alphabet
and
compare('E','L') > 0 // since 'E' is a child of 'L'
but
compare('G','L') < 0 // since 'G' comes before 'L' in the alphabet
Since your Comparator
is not a valid Comparator
, it is likely to yield either an exception or unexpected results.