I have a set of objects which have a name (a) and dependecies (b). I want to order the objects in a way where all previous dependecies are resolved. So I have this code:
import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
public class Foo {
static class TestOrder implements Comparable<TestOrder> {
private final String a;
private final Set<String> b;
public TestOrder(String a, Set<String> b) {
this.a = a;
this.b = b;
}
public int compareTo(TestOrder o) {
if (o.b.contains(a))
return -1;
else
return 1;
}
@Override
public int hashCode() {
return a.hashCode();
}
@Override
public boolean equals(Object obj) {
return a.equals(obj);
}
public String toString() {
return a + " - " + b.toString();
}
}
public static void main(String[] args) {
Set<TestOrder> tos = new TreeSet<>();
tos.add(new Foo.TestOrder("a", new HashSet<String>() {{
add("b");
add("c");
}}));
tos.add(new Foo.TestOrder("e", new HashSet<String>() {{
add("a");
}}));
tos.add(new Foo.TestOrder("b", new HashSet<String>() {{
add("d");
add("c");
}}));
tos.add(new Foo.TestOrder("c", new HashSet<String>() {{ }}));
tos.add(new Foo.TestOrder("d", new HashSet<String>() {{ }}));
for (TestOrder to : tos) {
System.out.println(to.toString());
}
}
}
which results in:
c - []
b - [d, c]
a - [b, c]
e - [a]
d - []
but - since b depends on d - the expected result would be:
c - []
d - []
b - [d, c]
a - [b, c]
e - [a]
What am I missing?
You are missing several things (in the harder-to-fix order, starting with the easier ones):
You can fix the first two relatively easily by checking the dependency of this
on o
before returning 1
, and using a.compareTo(o.a)
for tie-breaking.
public int compareTo(TestOrder o) {
if (o.b.contains(a))
return -1;
else if (b.contains(o.a))
return 1;
else
return a.compareTo(o.a);
}
The third one could be fixed by switching to an array, and sorting it only after all the insertions have been made.
The last one, however, is very bad: in order to fix it, each item needs to know about the rest of the collection. I do not see a good way out of this, so I suggest using a traditional topological sorting algorithm to order your dependencies, rather than trying to shoehorn that problem in the framework of Java collections.