The problem is, triads do not show up to the fight. In fact, printing gangs.size() right at the start of doBattle() returns 3 instead of 4. Why?
Both triads
and grove street
have a strength of 9. Therefore they're equal in terms of Gang.compareTo
(implementing Comparable
). Therefore only one is permitted in a TreeSet
.
If you don't want to remove items which are duplicates in terms of their sort order, don't use a TreeSet
...
EDIT: The ComparableGang
interface description indicates what's expected:
/** An `IGang` ordered by identity (name) */
public interface ComparableGang extends IGang, Comparable<IGang> {}
Your compareTo
method does not order "by identity (name)" - it orders by strength. To be honest, it's a pretty stupid interface in the first place, as it would have been perfectly easy for asoft
to create a class of public class GangNameComparator : Comparator<IGang>
, and then supply that as the comparator to the tree set if they wanted to order by name.
However, as they're suggesting that you should implement the comparison, you need to do so as the interface describes:
public int compareTo(IGang g) {
return name.compareTo(g.getName());
}
However... as you note in comments (and as noted in Rob's answer), this then contradicts the convention-bustingly-named IGang
description:
public interface IGang {
/** @return negative, 0, or positive, respectively
* if this gang is weaker than, equal to, or stronger
* than the other
*/
public int compareTo(IGang g);
}
It's impossible to implement ComparableGang
to satisfy both its own documentation and the IGang
documentation. This is basically broken by design, on asoft's part.
Any code should be able to use an IGang
implementation, knowing only about IGang
, and relying on the implementation following the IGang
contract. However, asoft broke that assumption by requiring different behaviour in an interface extending IGang
.
It would have been reasonable for them to add more requirements in ComparableGang
, so long as they didn't violate the existing requirements of IGang
.
Note that this is an important difference between C# and Java. In C#, two functions in two different interfaces with the same signature can be combined into one interface that inherits both of them and the two methods remain distinct and accessible. In Java, the two methods, since they are completely abstract and have the same signature, are considered to be the same method and a class implementing the combined interfaces has only one such method. So in Java ComparableGang
is invalid because it cannot have an implementation of compareTo() that satisfies the contract of ComparableGang and the contract of IGang.