¿Cuándo debe ser una clase comparable y / o comparadora?

138

He visto clases que implementan Comparable y Comparator . ¿Qué significa esto? ¿Por qué usaría uno sobre el otro?

Nick Heiner
fuente
18
¿Has leído el javadoc sobre ellos? Describe lo diferente con bastante claridad.
skaffman
1
Qué es comparable y comparador y cuándo usar comparable y comparador. Para saber esto lea este enlace. Esto le ayudará a comprender su comportamiento y uso. http://iandjava.blogspot.in/2012/10/comparable-and-comparator.html
RockStar
66
Esta es una buena pregunta con una buena respuesta objetiva. Estoy consternado de que esté cerrado.
Russell Silva
3
Otras preguntas sobre StackOverflow se refieren a esto como la pregunta definitiva "¿Cuál es la diferencia entre comparador y comparable"? ¿Por qué está marcado como "no constructivo"? Como novato en Java, ¡esta fue una pregunta muy útil!
Pete

Respuestas:

241

El siguiente texto proviene de Comparador vs Comparable

Comparable

Un objeto comparable es capaz de compararse con otro objeto. La clase misma debe implementar la java.lang.Comparableinterfaz para poder comparar sus instancias.

Comparador

Un objeto de comparación es capaz de comparar dos objetos diferentes. La clase no compara sus instancias, sino las instancias de otras clases. Esta clase de comparación debe implementar la java.util.Comparatorinterfaz.

Dan
fuente
Para obtener una explicación detallada de los usos de Comparator y comparable: sysdotoutdotprint.com/index.php/2017/03/28/…
mel3kings
2
Otro buen artículo: codecramp.com/java-comparable-vs-comparator
EMM
@ mel3kings: el enlace ya no es accesible.
Gaurav
152

Implementar Comparablesignifica " puedo compararme con otro objeto " . Esto suele ser útil cuando hay una única comparación natural por defecto.

Implementar Comparatorsignifica " puedo comparar otros dos objetos " . Esto suele ser útil cuando hay múltiples formas de comparar dos instancias de un tipo, por ejemplo, podría comparar personas por edad, nombre, etc.

Jon Skeet
fuente
1
Hola skeet, ¿puedes dejar el código usando comparable y comparador?
Mdhar9e
55
@ mdhar9e: Hay muchos ejemplos: si le resulta difícil traducirlos a su escenario específico, brinde más información en una nueva pregunta.
Jon Skeet
2
@alireza: Ya he dado un ejemplo en el segundo párrafo: al tener diferentes comparadores, puede ordenar la misma colección (personas) por diferentes propiedades (edad, nombre, etc.). No puede hacer eso simplemente haciendo un Personimplemento Comparable, porque no puede cambiar cómo se comparan dos personas.
Jon Skeet
1
@feelgoodandprogramming: No, esos son algoritmos de clasificación diferentes . Hay potencialmente tres piezas de código aquí, en tres clases diferentes: 1) La entidad misma, por ejemplo Person. 2) El comparador, por ejemplo, PersonAgeComparatorque es capaz de comparar dos entidades diferentes y decidir cuál debe venir primero en ese orden de clasificación particular. 3) El código de clasificación, que toma una colección de entidades y un comparador, y clasifica esa colección usando el comparador para determinar el orden.
Jon Skeet
2
@RishiKeshPathak: Bueno, es más que uses Comparable si solo hay una cosa obvia para comparar. E incluso entonces usted puede simplemente escribir un comparador. Si tiene dos programas diferentes que usan la misma clase, y uno quiere ordenar por edad y el otro por nombre, al menos uno de ellos necesitará usar un Comparador.
Jon Skeet
38

Comparable permite que una clase implemente su propia comparación:

  • está en la misma clase (a menudo es una ventaja)
  • solo puede haber una implementación (por lo que no puede usarla si desea dos casos diferentes)

En comparación, Comparator es una comparación externa:

  • normalmente se encuentra en una instancia única (ya sea en la misma clase o en otro lugar)
  • que nombre a cada aplicación con la forma en que desea ordenar las cosas
  • puedes proporcionar comparadores para clases que no controlas
  • la implementación se puede usar incluso si el primer objeto es nulo

En ambas implementaciones, aún puede elegir lo que desea comparar . Con los genéricos, puede declararlo y verificarlo en tiempo de compilación. Esto mejora la seguridad, pero también es un desafío determinar el valor apropiado.

Como guía, generalmente uso la clase o interfaz más general con la que se puede comparar ese objeto, en todos los casos de uso que imagino ... ¡Sin embargo, no es una definición muy precisa! :-(

  • Comparable<Object>le permite usarlo en todos los códigos en tiempo de compilación (que es bueno si es necesario, o malo si no y pierde el error en tiempo de compilación); su implementación tiene que hacer frente a los objetos y lanzarlos según sea necesario, pero de manera robusta.
  • Comparable<Itself> Es muy estricto al contrario.

Es curioso, cuando subclases a Subclase, la Subclase también debe ser Comparable y robusta (o rompería el Principio de Liskov y te daría errores de tiempo de ejecución).

KLE
fuente
20

java.lang.Comparable

  1. Para implementar la Comparableinterfaz, la clase debe implementar un método únicocompareTo()

    int a.compareTo(b)

  2. Debe modificar la clase cuya instancia desea ordenar. Para que solo se pueda crear una secuencia de clasificación por clase.

java.util.Comparator

  1. Para implementar la interfaz Comparator, la clase debe implementar un método único compare()

    int compare (a,b)

  2. Construye una clase separada de la clase cuya instancia desea ordenar. Para que se pueda crear una secuencia de clasificación múltiple por clase.
codiacTushki
fuente
14

Comparable es para proporcionar un orden predeterminado en los objetos de datos, por ejemplo, si los objetos de datos tienen un orden natural.

A Comparatorrepresenta el pedido en sí para un uso específico.

starblue
fuente
8

Comparablegeneralmente se prefiere. Pero a veces una clase ya se implementa Comparable, pero desea ordenar en una propiedad diferente. Entonces te ves obligado a usar a Comparator.

Algunas clases en realidad prevén Comparatorscasos comunes; por ejemplo, los Strings distinguen entre mayúsculas y minúsculas cuando se ordenan, pero también hay una Comparatorllamada estática CASE_INSENSITIVE_ORDER.

Michael Myers
fuente
77
No estoy seguro de estar de acuerdo con que Comparable sea el preferido. Algunos objetos tienen un fuerte sentido del orden natural, a saber, los números, en todas sus formas: números naturales, números reales, fechas, etc. Pero incluso otros objetos relativamente primitivos como las cadenas de caracteres carecen de un orden universalmente aplicable. En el caso de objetos más complejos como una entidad de un modelo de dominio de aplicación, la implementación de Comparable suele ser un error. Sus muchas propiedades hacen que sea demasiado difícil anticipar qué orden se querrá con mayor frecuencia.
erickson
6

Aquí hay algunas diferencias entre Comparator y Comparable que encontré en la web:

  1. Si ve que la diferencia lógica entre estos dos es Comparador en Java, compare dos objetos proporcionados a él, mientras que la interfaz Comparable compara "esta" referencia con el objeto especificado.

  2. Comparable en Java se utiliza para implementar el orden natural del objeto. En Java API String, las clases Date y wrapper implementan una interfaz comparable.

  3. Si alguna clase implementa una interfaz comparable en Java, la colección de ese objeto, ya sea List o Array, se puede ordenar automáticamente utilizando el método Collections.sort () o Array.sort () y el objeto se ordenará según el orden natural definido por el método CompareTo.

  4. Los objetos que implementan Comparable en Java se pueden usar como claves en un mapa ordenado o elementos en un conjunto ordenado, por ejemplo TreeSet, sin especificar ningún Comparador.

sitio: ¿Cómo usar Comparator y Comparable en Java? Con el ejemplo

Leer más: ¿Cómo usar Comparator y Comparable en Java? Con el ejemplo

Javapassion
fuente
5

Comparablees para objetos con un orden natural. El objeto mismo sabe cómo se debe ordenar.
Comparatores para objetos sin un orden natural o cuando desea utilizar un orden diferente.

Michael Lloyd Lee mlk
fuente
4

Diferencia entre comparador e interfaces comparables

Comparable se usa para compararse al usar con otro objeto.

Comparator Se utiliza para comparar dos tipos de datos que son objetos.

SravaniChowdary.Gorijavolu
fuente
2

Si ve que la diferencia lógica entre estos dos está Comparatoren Java, compare dos objetos proporcionados a él, mientras que la Comparableinterfaz compara "esta" referencia con el objeto especificado.

Comparableen Java se usa para implementar el ordenamiento natural del objeto. En Java API String, las clases Date y wrapper implementan la Comparableinterfaz.

Si alguna clase implementa una Comparableinterfaz en Java, entonces la colección de ese objeto puede Listo Arrayse puede ordenar automáticamente usando Collections.sort()o Array.sort()método y el objeto se ordenará según el orden natural definido por el compareTométodo.

Los objetos que se implementan Comparableen Java pueden usarse como claves en un mapa ordenado o elementos en un conjunto ordenado, por ejemplo TreeSet, sin especificar ninguno Comparator.

Srinivas
fuente
0

Mi lib de anotación para implementar Comparable y Comparator:

public class Person implements Comparable<Person> {         
    private String firstName;  
    private String lastName;         
    private int age;         
    private char gentle;         

    @Override         
    @CompaProperties({ @CompaProperty(property = "lastName"),              
        @CompaProperty(property = "age",  order = Order.DSC) })           
    public int compareTo(Person person) {                 
        return Compamatic.doComparasion(this, person);         
    }  
} 

Haga clic en el enlace para ver más ejemplos. comparativo

Jianmin Liu
fuente
3
Bienvenido a stackoverflow. Esta pregunta es antigua y ya fue respondida. Por lo general, es mejor no resucitar hilos obsoletos a menos que su respuesta contribuya con algo significativamente nuevo o diferente a las respuestas anteriores.
Oers