Estoy implementando un compareTo()
método para una clase simple como esta (para poder usar Collections.sort()
y otras cosas que ofrece la plataforma Java):
public class Metadata implements Comparable<Metadata> {
private String name;
private String value;
// Imagine basic constructor and accessors here
// Irrelevant parts omitted
}
Quiero que el orden natural de estos objetos sea: 1) ordenado por nombre y 2) ordenado por valor si el nombre es el mismo; ambas comparaciones deben ser insensibles a mayúsculas y minúsculas. Para ambos campos, los valores nulos son perfectamente aceptables, por lo compareTo
que no deben romperse en estos casos.
La solución que me viene a la mente es la siguiente: (estoy usando "cláusulas de protección" aquí, mientras que otros prefieren un único punto de retorno, pero eso no viene al caso):
// 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);
}
Esto hace el trabajo, pero no estoy perfectamente satisfecho con este código. Es cierto que no es muy complejo, pero es bastante detallado y tedioso.
La pregunta es, ¿cómo haría esto menos detallado (al tiempo que conserva la funcionalidad)? No dude en consultar las bibliotecas estándar de Java o Apache Commons si le ayudan. ¿La única opción para simplificar esto (un poco) sería implementar mi propio "NullSafeStringComparator" y aplicarlo para comparar ambos campos?
Ediciones 1-3 : Eddie tiene razón; arreglado el caso anterior de "ambos nombres son nulos"
Sobre la respuesta aceptada
Hice esta pregunta en 2009, en Java 1.6, por supuesto, y en ese momento la solución JDK pura de Eddie era mi respuesta preferida preferida. Nunca tuve la oportunidad de cambiar eso hasta ahora (2017).
También hay soluciones de bibliotecas de terceros, una de Apache Commons Collections 2009 y una de Guava 2013, ambas publicadas por mí, que preferí en algún momento.
Ahora hice que la solución Java 8 limpia de Lukasz Wiktor fuera la respuesta aceptada. Eso definitivamente debería preferirse si está en Java 8, y actualmente Java 8 debería estar disponible para casi todos los proyectos.