Implementuję compareTo()
metodę dla prostej klasy, takiej jak ta (aby móc korzystać z Collections.sort()
innych dobrodziejstw oferowanych przez platformę Java):
public class Metadata implements Comparable<Metadata> {
private String name;
private String value;
// Imagine basic constructor and accessors here
// Irrelevant parts omitted
}
Chcę, aby te obiekty były uporządkowane w sposób naturalny : 1) posortowane według nazwy i 2) posortowane według wartości, jeśli nazwa jest taka sama; w obu porównaniach nie należy rozróżniać wielkości liter. Dla obu pól wartości null są całkowicie akceptowalne, więc compareTo
w takich przypadkach nie wolno ich łamać.
Rozwiązanie, które przychodzi na myśl, wygląda następująco (używam tutaj „klauzul ochronnych”, podczas gdy inni mogą preferować pojedynczy punkt powrotu, ale to nie ma znaczenia):
// 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);
}
To działa, ale nie jestem do końca zadowolony z tego kodu. Wprawdzie nie jest to zbyt skomplikowane, ale jest dość rozwlekłe i żmudne.
Pytanie brzmi, jak uczynić to mniej szczegółowym (zachowując funkcjonalność)? Jeśli pomogą, możesz odwołać się do standardowych bibliotek Java lub Apache Commons. Czy jedyną opcją, aby to (trochę) uprościć, byłoby zaimplementowanie własnego „NullSafeStringComparator” i zastosowanie go do porównania obu pól?
Edycje 1-3 : Eddie ma rację; naprawiono powyższy przypadek "obie nazwy są puste"
O przyjętej odpowiedzi
Zadałem to pytanie w 2009 roku, oczywiście na Javie 1.6, a wtedy czyste rozwiązanie JDK autorstwa Eddiego było moją preferowaną akceptowaną odpowiedzią. Nigdy nie udało mi się tego zmienić aż do teraz (2017).
Istnieją również rozwiązania biblioteczne innych firm - 2009 Apache Commons Collections i 2013 Guava, oba opublikowane przeze mnie - które wolałem w pewnym momencie.
Teraz zaakceptowałem odpowiedź z czystego rozwiązania Java 8 autorstwa Łukasza Wiktora . Powinno to być zdecydowanie preferowane, jeśli jest to Java 8, a obecnie Java 8 powinna być dostępna dla prawie wszystkich projektów.