2010-06-02 19 views
5

Tengo un método que necesita un Comparator para uno de sus parámetros. Me gustaría pasar un Comparator que hace una comparación normal y un comparador inverso que lo hace a la inversa.Comparador directo en Java de fábrica

java.util.Collections proporciona un reverseOrder() esto es bueno para la comparación inversa, pero no pude encontrar ningún Comparator normal.

La única solución que se me vino a la mente es Collections.reverseOrder(Collections.reverseOrder()). pero no me gusta porque el doble método llama al interior.

Por supuesto que podría escribir un NormalComparator así:

public class NormalComparator<T extends Comparable> implements Comparator<T> { 
    public int compare(T o1, T o2) { 
     return o1.compareTo(o2); 
    } 
} 

Pero estoy realmente sorprendido de que Java no tiene una solución para este fuera de la caja.

Respuesta

6

La mayoría de los lugares donde se puede especificar un Comparator también tienen una versión sin utilizar un Comparator en absoluto en cuyo caso se utiliza el orden natural (es decir, se espera que todos los objetos que implementan Comparable y utiliza compareTo).

Así que la solución habitual para esto es no especificar un Comparator en absoluto. ¿Tiene un caso específico donde solo se admite el enfoque Comparator?

Si lo necesita absolutamente, la Google Collections (así como Guava, que es un superconjunto de las Colecciones de Google) proporciona Ordering.natural() que devuelve a Ordering object que representan el orden natural según la definición de la interfaz Comparable. Ordering implementa Comparator, por lo que simplemente puede usar eso.

+0

Es mi método, así que no tiene un orden natural. (en realidad lo ha hecho, porque lo escribí para trabajar, pero no quería, estoy buscando una solución más agradable) –

+0

Y sí, lo escribí porque busqué la fuente de 'HashTree'. –

+0

@KARASZI: que '' HashTree' estás hablando? No hay tal clase en Java SE. ¿Querías decir 'TreeMap'? –

0

Para uso ordenación inversa Collections.reverseOrder() ...

Devuelve un comparador que impone el reverso de la ordenación natural en una colección de objetos que implementan la interfaz Comparable.

+0

no entendiste la pregunta. Quiero un directo también, no solo al revés. El doble reverso podría ser el normal –

+0

@ István: Para el ordenamiento natural, implemente el SimpleComparator simple para objetos Comparables. No puedo encontrar uno en las bibliotecas estándar. –

+0

estaba en el OP, como se puede ver –

0

Hay por lo general no hay necesidad de un orden natural Comparator<T>, ya que por lo general hay una sobrecarga que toma un Comparable<T>. Siempre se puede seguir el ejemplo establecido por Collections.reverseOrder() y escribir algo como esto:

private static final Comparator<?> NATURAL_ORDER = 
    new Comparator<Comparable<Object>>() { 
    @Override public int compare(Comparable<Object> o1, Comparable<Object> o2) { 
     return o1.compareTo(o2); 
    } 
    }; 

@SuppressWarnings("unchecked") 
public static <T> Comparator<T> naturalOrder() { 
    return (Comparator<T>) NATURAL_ORDER; 
} 

A continuación, puede escribir algo como:

List<String> names = Arrays.asList("Bob", "Alice", "Carol"); 
Collections.sort(names, naturalOrder()); 
System.out.println(names); 
// prints "[Alice, Bob, Carol]" 
+0

como pudieron ver en el OP, ¡eso es lo que hice! –

1

Pero estoy realmente sorprendido de que Java no tiene una solución para esto fuera de la caja.

Supongo que sería útil en algunos casos ... como el tuyo. Pero en la mayoría de los casos de uso una aplicación simplemente usaría el método compareTo del objeto directamente.La indirecta a través de un objeto Comparator no serviría de nada ... la mayor parte del tiempo.

Supongo que los diseñadores de esas API de Java no consideraron su caso de uso lo suficientemente importante como para admitir directamente. Además, su implementación es solo de cuatro líneas de código.

Las bibliotecas de clases de Java no son perfectas. Aprende a vivir con ello :-).

+0

Y aceptan un 'null' en cada método donde se necesitaba un' Comparator' (y pegaron el método 'compareTo' en lugar de crear un nuevo' NaturalComparator' en su lugar), por lo que realmente no es una solución ** DRY **. yo pienso ... –

Cuestiones relacionadas