Ich implementiere eine compareTo()
Methode für eine einfache Klasse wie diese (um Collections.sort()
andere von der Java-Plattform angebotene Extras verwenden zu können ):
public class Metadata implements Comparable<Metadata> {
private String name;
private String value;
// Imagine basic constructor and accessors here
// Irrelevant parts omitted
}
Ich möchte, dass die natürliche Reihenfolge für diese Objekte wie folgt lautet: 1) sortiert nach Namen und 2) sortiert nach Wert, wenn der Name derselbe ist; Bei beiden Vergleichen sollte die Groß- und Kleinschreibung nicht berücksichtigt werden. Für beide Felder sind Nullwerte durchaus akzeptabel und compareTo
dürfen in diesen Fällen nicht unterbrochen werden.
Die Lösung, die mir in den Sinn kommt, sieht wie folgt aus (ich verwende hier "Schutzklauseln", während andere vielleicht einen einzelnen Rückgabepunkt bevorzugen, aber das ist nebensächlich):
// 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);
}
Das macht den Job, aber ich bin mit diesem Code nicht ganz zufrieden. Zugegeben, es ist nicht sehr komplex, aber ziemlich ausführlich und langweilig.
Die Frage ist, wie würden Sie dies weniger ausführlich machen (unter Beibehaltung der Funktionalität)? Sie können sich gerne auf Java-Standardbibliotheken oder Apache Commons beziehen, wenn diese helfen. Wäre die einzige Möglichkeit, dies (ein wenig) einfacher zu machen, die Implementierung meines eigenen "NullSafeStringComparator" und dessen Anwendung zum Vergleich beider Felder?
Änderungen 1-3 : Eddie hat recht; Der obige Fall "beide Namen sind null" wurde behoben
Über die akzeptierte Antwort
Ich habe diese Frage bereits 2009 gestellt, natürlich auf Java 1.6, und zu der Zeit war die reine JDK-Lösung von Eddie meine bevorzugte akzeptierte Antwort. Ich bin bis jetzt (2017) nie dazu gekommen, das zu ändern.
Es gibt auch Bibliothekslösungen von Drittanbietern - eine Apache Commons Collections 2009 und eine Guava 2013, die beide von mir veröffentlicht wurden -, die ich zu einem bestimmten Zeitpunkt bevorzugt habe.
Ich habe jetzt die saubere Java 8-Lösung von Lukasz Wiktor zur akzeptierten Antwort gemacht. Dies sollte auf jeden Fall unter Java 8 bevorzugt werden, und heutzutage sollte Java 8 für fast alle Projekte verfügbar sein.