example - how to use comparator java
Contrato comparable y comparador con respecto a nulo (3)
¿Alguna vez es una buena idea incluso tener que ordenar una lista que contenga elementos nulos, o es una señal segura de un error de diseño?
Bueno, probablemente no tenga sentido que la lista contenga un Objeto nulo, pero tal vez su Lista contenga un "objeto comercial" y usted puede ordenar las diferentes propiedades del objeto comercial, algunas de las cuales pueden contener nulos.
¿Es este un uso aceptable de un Comparador?
BeanComparator permite ordenar una propiedad en un objeto comercial, incluso si la propiedad contiene nulo, por lo que tendría que decir que es un uso aceptable de un Comparador.
Comparable
contrato Comparable
especifica que e.compareTo(null)
debe lanzar NullPointerException
.
De la API :
Tenga en cuenta que
null
no es una instancia de ninguna clase, ye.compareTo(null)
debería arrojar unaNullPointerException
aunquee.equals(null)
devuelvefalse
.
Por otro lado, Comparator
API no menciona nada sobre lo que debe suceder al comparar null
. Considera el siguiente intento de un método genérico que toma un Comparable
, y devuelve un Comparator
que pone null
como el elemento mínimo.
static <T extends Comparable<? super T>> Comparator<T> nullComparableComparator() {
return new Comparator<T>() {
@Override public int compare(T el1, T el2) {
return
el1 == null ? -1 :
el2 == null ? +1 :
el1.compareTo(el2);
}
};
}
Esto nos permite hacer lo siguiente:
List<Integer> numbers = new ArrayList<Integer>(
Arrays.asList(3, 2, 1, null, null, 0)
);
Comparator<Integer> numbersComp = nullComparableComparator();
Collections.sort(numbers, numbersComp);
System.out.println(numbers);
// "[null, null, 0, 1, 2, 3]"
List<String> names = new ArrayList<String>(
Arrays.asList("Bob", null, "Alice", "Carol")
);
Comparator<String> namesComp = nullComparableComparator();
Collections.sort(names, namesComp);
System.out.println(names);
// "[null, Alice, Bob, Carol]"
Entonces las preguntas son:
- ¿Es este un uso aceptable de un
Comparator
, o está violando una regla no escrita en cuanto a compararnull
y arrojarNullPointerException
? - ¿Alguna vez es una buena idea incluso tener que ordenar una
List
contenga elementosnull
, o es una señal segura de un error de diseño?
¿Alguna vez es una buena idea incluso tener que ordenar una lista que contenga elementos nulos, o es una señal segura de un error de diseño?
Conceptualmente, null significa "nada", y no colocar nada en una lista me parece extraño. Además, el contrato de la Lista de Java establece que
Algunas implementaciones de lista tienen restricciones sobre los elementos que pueden contener. Por ejemplo, algunas implementaciones prohíben elementos nulos
por lo tanto, ni siquiera se requiere una implementación de Lista en Java para admitir elementos nulos. En resumen, si no tiene una buena razón para poner nulo en una lista, no lo haga, y si lo hace, pruebe que realmente funciona como se esperaba.
Comparable
no permite null
simplemente porque:
a.compareTo(b) == -b.compareTo(a)
para todos los objetos a
y b
donde !a.equals(b)
. Más específicamente:
a.equals(b) ? b.equals(a) && a.compareTo(b) == 0 &&
b.compareTo(a) == 0 && a.hashCode() == b.hashCode()
: !b.equals(a) && a.compareTo(b) != 0 &&
a.compareTo(b) == -b.compareTo(a)
debe evaluar a true
para cumplir con los contratos relevantes.
Entonces null
no está permitido porque no puedes hacer:
null.compareTo(a)
Comparator
es más flexible, por lo que el manejo de null
es un problema específico de la implementación. Apóyalo o no según lo que quieras que haga tu Comparator
.