What should int compareTo() return when the parameter string is null?
It would be a bad practice to not throw an exception because it violates the transitive antisymmetric nature of compareTo.
From Comparable.compareTo documentation:
The implementor must ensure sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) for all x and y. (This implies that x.compareTo(y) must throw an exception iff y.compareTo(x) throws an exception.)
The implementor must also ensure that the relation is transitive: (x.compareTo(y)>0 && y.compareTo(z)>0) implies x.compareTo(z)>0.
Finally, the implementor must ensure that x.compareTo(y)==0 implies that sgn(x.compareTo(z)) == sgn(y.compareTo(z)), for all z.
More importantly, it's a bad idea to use compareTo on your objects to compare them with strings, for the same reason: sign(obj.compareTo(str)) != -sign(str.compareTo(obj))
. Implement a custom Comparator and do whatever you want in it.
From javadoc for Comparable
Note that null is not an instance of any class, and e.compareTo(null) should throw a NullPointerException even though e.equals(null) returns false.
Yes, there is no problem allowing null
for instance fields - just make sure its sorting order is defined. Most natural would be putting it either before or after all real strings, but you could do anything here, just do it consistently. (For example, you could sort null
like "null"
.)
Here is an example implementation for a single member:
class Example implements Comparable<Example> {
@Nullable
private String member;
// TODO: getter, setter, constructor, ...
public int compareTo(Example that) {
if(this.member == null)
if(that.member == null)
return 0; //equal
else
return -1; // null is before other strings
else // this.member != null
if(that.member == null)
return 1; // all other strings are after null
else
return this.member.compareTo(that.member);
}
}
Please note that the specification of Comparable.compareTo() only has a constraint for o.compareTo(null)
(which should behave just like - null.compareTo(o)
, i.e. throw a NullPointerException), but not about how null
fields are handled (it doesn't mention fields at all, so a class could return whatever it wants, as long as the antisymmetry, reflexivity and transitivity is ensured).