I'm implementing compareTo()
method for a simple class such as this (to be able to use Collections.sort()
and other goodies offered by the Java platform):
public class Metadata implements Comparable<Metadata> {
private String name;
private String value;
// Imagine basic constructor and accessors here
// Irrelevant parts omitted
}
I want the natural ordering for these objects to be: 1) sorted by name and 2) sorted by value if name is the same; both comparisons should be case-insensitive. For both fields null values are perfectly acceptable, so compareTo
must not break in these cases.
The solution that springs to mind is along the lines of the following (I'm using "guard clauses" here while others might prefer a single return point, but that's beside the point):
// primarily by name, secondarily by value; null-safe; case-insensitive
public int compareTo(Metadata other) {
if (this.name == null && other.name != null){
return -1;
}
else if (this.name != null && other.name == null){
return 1;
}
else if (this.name != null && other.name != null) {
int result = this.name.compareToIgnoreCase(other.name);
if (result != 0){
return result;
}
}
if (this.value == null) {
return other.value == null ? 0 : -1;
}
if (other.value == null){
return 1;
}
return this.value.compareToIgnoreCase(other.value);
}
This does the job, but I'm not perfectly happy with this code. Admittedly it isn't very complex, but is quite verbose and tedious.
The question is, how would you make this less verbose (while retaining the functionality)? Feel free to refer to Java standard libraries or Apache Commons if they help. Would the only option to make this (a little) simpler be to implement my own "NullSafeStringComparator", and apply it for comparing both fields?
Edits 1-3: Eddie's right; fixed the "both names are null" case above