systemproperty property java comparison null

property - list system properties java



¿Qué hacer con los campos nulos en compare()? (10)

Creo que las declaraciones de devolución anticipadas serían la otra alternativa a muchos ifs

p.ej

if(o1==null) return x; if(o2==null) return x; if(o1.getBar()==null) return x; if(o2.getBar()==null) return x; // No null checks needed from this point.

En Java, utilizo una clase en la que algunos campos pueden ser null . Por ejemplo:

class Foo { String bar; //.... }

Quiero escribir un BarComparator para esta clase,

private static class BarComparator implements Comparator<Foo> { public int compare( final Foo o1, final Foo o2 ) { // Implementation goes here } }

¿Existe una forma estándar de lidiar con el hecho de que cualquiera de o1 , o2 , o1.bar , o2.bar puede ser null , sin escribir muchos anidados if ... else ?

¡Aclamaciones!


Depende de si considera que una entrada nula es un valor de cadena válido que vale la pena comparar. es nulo <o> "manzana". Lo único que puedo decir con certeza es que null == null. Si puede definir dónde encaja nulo en el orden, entonces puede escribir el código apropiadamente.

En este caso, podría elegir arrojar NullPointerExcpetion o IllegalArgumentException e intentar manejar el nulo en un nivel superior al no incluirlo en la comparación en primer lugar.


Gracias por las respuestas! El método genérico y Google Comparators se ven interesantes.

Y descubrí que hay un NullComparator en las Colecciones de Apache Commons (que estamos usando actualmente):

private static class BarComparator implements Comparator<Foo> { public int compare( final Foo o1, final Foo o2 ) { // o1.bar & o2.bar nulleness is taken care of by the NullComparator. // Easy to extend to more fields. return NULL_COMPARATOR.compare(o1.bar, o2.bar); } private final static NullComparator NULL_COMPARATOR = new NullComparator(false); }

Nota: Me centré en el campo de la bar aquí para mantenerlo al grano.


La clave aquí es determinar cómo te gustaría que los nulos sean tratados. Algunas opciones son: a) suponer que los nulos vienen antes que todos los demás objetos en orden de clasificación b) suponer que los nulos vienen después de todos los demás objetos en orden de clasificación c) tratar nulo como equivalente a algún valor predeterminado d) tratar nulos como condiciones de error. El que elija dependerá por completo de la aplicación en la que esté trabajando.

En el último caso, por supuesto, lanzas una excepción. Para los demás, necesitas un caso de cuatro vías if / else (unos tres minutos para codificar uno, has averiguado qué quieres que sean los resultados).


Me parece que no hay un método para hacerlo, pero de todos modos el código no es tan largo.


No debe usar el NullComparator de la manera en que lo hace; está creando una nueva instancia de la clase para cada operación de comparación, y si, por ejemplo, está ordenando una lista con 1000 entradas, eso será 1000 * log2 (1000) objetos que son completamente superfluas Esto puede volverse problemático rápidamente.

O subclasifique o delegue en él, o simplemente implemente su propia verificación nula: realmente no es tan complejo:

private static class BarComparator implements Comparator<Foo> { private NullComparator delegate = new NullComparator(false); public int compare( final Foo o1, final Foo o2 ) { return delegate.compare(o1.bar, o2.bar); } }


Puedes escribir tu Comparador para eso. Digamos que tienes una persona de clase con nombre de cadena como campo privado. getName () y setName () método para acceder al nombre del campo. Debajo está el Comparador para la clase Persona.

Collections.sort(list, new Comparator<Person>() { @Override public int compare(Person a, Person b) { if (a == null) { if (b == null) { return 0; } return -1; } else if (b == null) { return 1; } return a.getName().compareTo(b.getName()); } });

Actualizar:

A partir de Java 8, puede utilizar las API a continuación para la Lista.

// Push nulls at the end of List Collections.sort(subjects1, Comparator.nullsLast(String::compareTo)); // Push nulls at the beginning of List Collections.sort(subjects1, Comparator.nullsFirst(String::compareTo));


Si está utilizando colecciones de Google, puede encontrar útil la clase Comparadores . Si tiene métodos de ayuda para ordenar nulos como el elemento más grande o menos en la colección. Puede usar comparadores compuestos para ayudar a reducir la cantidad de código.


Supongo que podría envolver la llamada al método compareTo de campo con un pequeño método estático para ordenar los valores nulos altos o bajos:

static <T extends Comparable<T>> int cp(T a, T b) { return a==null ? (b==null ? 0 : Integer.MIN_VALUE) : (b==null ? Integer.MAX_VALUE : a.compareTo(b)); }

Uso simple (campos múltiples es como lo haría normalmente):

public int compare( final Foo o1, final Foo o2 ) { return cp(o1.field, o2.field); }


También existe la clase org.springframework.util.comparator.NullSafeComparator en Spring Framework que puede usar.

Ejemplo (Java 8):

SortedSet<Foo> foos = new TreeSet<>( ( o1, o2 ) -> { return new NullSafeComparator<>( String::compareTo, true ).compare( o1.getBar(), o2.getBar() ); } ); foos.add( new Foo(null) ); foos.add( new Foo("zzz") ); foos.add( new Foo("aaa") ); foos.stream().forEach( System.out::println );

Esto se imprimirá:

Foo{bar=''null''} Foo{bar=''aaa''} Foo{bar=''zzz''}