J'implémente une compareTo()
méthode pour une classe simple comme celle-ci (pour pouvoir utiliser Collections.sort()
et d'autres goodies offerts par la plate-forme Java):
public class Metadata implements Comparable<Metadata> {
private String name;
private String value;
// Imagine basic constructor and accessors here
// Irrelevant parts omitted
}
Je veux que l' ordre naturel de ces objets soit: 1) trié par nom et 2) trié par valeur si le nom est le même; les deux comparaisons doivent être insensibles à la casse. Pour les deux champs, les valeurs nulles sont parfaitement acceptables et compareTo
ne doivent donc pas être interrompues dans ces cas.
La solution qui me vient à l'esprit est la suivante (j'utilise ici des «clauses de garde», tandis que d'autres préfèrent peut-être un seul point de retour, mais ce n'est pas la question):
// 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);
}
Cela fait le travail, mais je ne suis pas parfaitement satisfait de ce code. Certes, ce n'est pas très complexe, mais assez verbeux et fastidieux.
La question est, comment feriez-vous cela moins verbeux (tout en conservant la fonctionnalité)? N'hésitez pas à vous référer aux bibliothèques standard Java ou à Apache Commons si elles vous aident. Est-ce que la seule option pour rendre cela (un peu) plus simple serait d'implémenter mon propre "NullSafeStringComparator" et de l'appliquer pour comparer les deux champs?
Modifications 1 à 3 : à droite d'Eddie; correction du cas "les deux noms sont nuls" ci-dessus
À propos de la réponse acceptée
J'ai posé cette question en 2009, sur Java 1.6 bien sûr, et à l'époque la solution JDK pure d'Eddie était ma réponse acceptée préférée. Je n'ai jamais eu l'occasion de changer cela jusqu'à maintenant (2017).
Il existe également des solutions de bibliothèque tierces - une Apache Commons Collections de 2009 et une 2013 Guava, toutes deux publiées par moi - que j'ai préférées à un moment donné.
J'ai maintenant fait le nettoyage solution Java 8 de Lukasz Wiktor la réponse acceptée. Cela devrait certainement être préféré si sur Java 8, et ces jours-ci, Java 8 devrait être disponible pour presque tous les projets.