¿Cuál es la diferencia entre compare () y compareTo ()?

110

¿Cuál es la diferencia entre los métodos compare()y los de Java compareTo()? ¿Esos métodos dan la misma respuesta?

Pops
fuente
1
¿A qué método de clase se refiere?
Markus Lausberg
para una explicación detallada de los usos de compare () y compareTo (): sysdotoutdotprint.com/index.php/2017/03/28/…
mel3kings

Respuestas:

160

Desde JavaNotes :

  • a.compareTo(b):
    Interfaz comparable: compara valores y devuelve un int que indica si los valores se comparan menor que, igual o mayor que.
    Si los objetos de su clase tienen un orden natural , implemente la Comparable<T>interfaz y defina este método. Todas las clases Java que tienen un orden natural implementar Comparable<T>- Ejemplo: String, clases de envoltura ,BigInteger

  • compare(a, b):
    Interfaz del comparador: compara los valores de dos objetos. Esto se implementa como parte de la Comparator<T>interfaz, y el uso típico es definir una o más pequeñas clases de utilidad que implementan esto, para pasar a métodos como sort()o para su uso ordenando estructuras de datos como TreeMapyTreeSet . Es posible que desee crear un objeto Comparador para lo siguiente:

    • Múltiples comparaciones . Proporcionar varias formas diferentes de ordenar algo. Por ejemplo, es posible que desee ordenar una clase Person por nombre, ID, edad, altura, ... Debería definir un Comparador para que cada uno de estos pase al sort()método.
    • Clase de sistema Para proporcionar métodos de comparación para clases sobre las que no tiene control. Por ejemplo, puede definir un Comparador para cadenas que las comparen por longitud.
    • Patrón de estrategia Para implementar un patrón de estrategia, que es una situación en la que desea representar un algoritmo como un objeto que puede pasar como parámetro, guardar en una estructura de datos, etc.

Si los objetos de su clase tienen un orden de clasificación natural, es posible que no necesite comparar ().


Resumen de http://www.digizol.com/2008/07/java-sorting-comparator-vs-comparable.html

Comparable
Un objeto comparable es capaz de compararse con otro objeto.

Comparador
Un objeto comparador es capaz de comparar dos objetos diferentes. La clase no está comparando sus instancias, sino las instancias de alguna otra clase.


Contextos de casos de uso:

Interfaz comparable

El método equals ==y los != operadores y prueban la igualdad / desigualdad, pero no proporcionan una forma de probar los valores relativos .
Algunas clases (por ejemplo, String y otras clases con un orden natural) implementan la Comparable<T>interfaz, que define un compareTo()método.
Querrás implementar Comparable<T>en tu clase si quieres usarlo con Collections.sort()oArrays.sort() métodos .

Definición de un objeto comparador

Puede crear comparadores para ordenar de cualquier forma arbitraria para cualquier clase .
Por ejemplo, la Stringclase define el CASE_INSENSITIVE_ORDERcomparador .


La diferencia entre los dos enfoques se puede vincular a la noción de:
Colección ordenada :

Cuando se ordena una colección, significa que puede iterar en la colección en un orden específico (no aleatorio) (a Hashtableno está ordenado).

Una colección con un orden natural no solo se ordena, sino que se ordena . ¡Definir un orden natural puede ser difícil! (como en el orden de cadena natural ).


Otra diferencia, señalada por HaveAGuess en los comentarios :

  • Comparable está en la implementación y no es visible desde la interfaz, por lo que cuando ordena no sabe realmente qué va a suceder.
  • Comparator le asegura que el orden estará bien definido.
VonC
fuente
2
Dado que esta respuesta es exhaustiva, aquí hay algo que me molesta de Comparable que le gustaría agregar: está en la implementación y no es visible desde la interfaz, por lo que cuando ordena, realmente no sabe qué va a suceder. El uso de un comparador le asegura que el orden estará bien definido
HaveAGuess
@HaveAGuess buen punto. He incluido su comentario en la respuesta para mayor visibilidad.
VonC
los objetos tienen un orden natural, ¿qué significa aquí el orden natural? ¿Es un miembro de datos de cadena para, por ejemplo, el nombre en la clase de empleado tiene un orden natural?
Narendra Jaggi
@NarendraJaggi Ver en.wikipedia.org/wiki/Enumeration . Un orden que facilita la enumeración. "Natural" en el sentido de que un buen orden en el conjunto de índices proporciona una forma única de enumerar el siguiente elemento dada una enumeración parcial
VonC
2
@VedantKekan Gracias. He restaurado 2 enlaces en esta respuesta.
VonC
16

compareTo()es de la Comparableinterfaz.

compare()es de la Comparatorinterfaz.

Ambos métodos hacen lo mismo, pero cada interfaz se usa en un contexto ligeramente diferente.

La interfaz Comparable se utiliza para imponer un orden natural a los objetos de la clase de implementación. El compareTo()método se denomina método de comparación natural. La interfaz Comparator se utiliza para imponer un orden total a los objetos de la clase de implementación. Para obtener más información, consulte los enlaces para saber exactamente cuándo usar cada interfaz.

Yuval Adam
fuente
¿Puedes dar algunos ejemplos? ¿Ambos métodos dan las mismas respuestas?
No sé por qué 'Comparable' es para pedidos naturales. Podemos personalizarlo, ¿no?
c-an
14

Similitudes:
ambas son formas personalizadas de comparar dos objetos.
Ambos devuelven unint descripción de la relación entre dos objetos.

Diferencias: el método compare()es un método que está obligado a implementar si implementa la Comparatorinterfaz. Le permite pasar dos objetos al método y devuelve una intdescripción de su relación.

Comparator comp = new MyComparator();
int result = comp.compare(object1, object2);

El método compareTo()es un método que está obligado a implementar si implementa la Comparableinterfaz. Permite comparar un objeto con objetos de tipo similar.

String s = "hi";
int result = s.compareTo("bye");

Resumen:
Básicamente son dos formas diferentes de comparar cosas.

jjnguy
fuente
9

Los métodos no tienen que dar las mismas respuestas. Eso depende de qué objetos / clases los llame.

Si está implementando sus propias clases que sabe que desea comparar en algún momento, puede hacer que implementen la interfaz Comparable e implementen el método compareTo () en consecuencia.

Si está utilizando algunas clases de una API que no implementan la interfaz Comparable, pero aún así desea compararlas. Es decir, para clasificar. Puede crear su propia clase que implemente la interfaz Comparator y en su método compare () implemente la lógica.

Nicolai
fuente
3

La interfaz comparable contiene un método llamado compareTo(obj)que toma solo un argumento y se compara con otra instancia u objetos de la misma clase.

La interfaz del comparador contiene un método llamado compare(obj1,obj2)que toma dos argumentos y compara el valor de dos objetos de la misma o diferentes clases.

dilip kumar
fuente
3
compareTo(T object)

proviene de la interfaz java.lang.Comparable, implementada para comparar este objeto con otro para dar un valor int negativo para que este objeto sea menor que, 0 para iguales o valor positivo para mayor que el otro. Este es el método de comparación más conveniente, pero debe implementarse en todas las clases que desee comparar.

compare(T obj1, T obj2)

proviene de la interfaz java.util.Comparator, implementada en una clase separada que compara los objetos de otra clase para dar un valor int negativo para el primer objeto que es menor que, 0 para iguales o valor positivo para mayor que el segundo objeto. Es necesario cuando no se puede hacer que una clase implemente compareTo () porque no es modificable. También se utiliza cuando desea diferentes formas de comparar objetos, no solo una (como por nombre o edad).

Dios ama a David
fuente
3

Usando Comparator, podemos tener un número n de lógica de comparación escrita para una clase .

P.ej

Para una clase de automóvil

Podemos tener una clase de Comparador para comparar según el número de modelo del automóvil. También podemos tener una clase de Comparador para comparar según el año del modelo del automóvil.

Clase de coche

public class Car  {

    int modelNo;

    int modelYear;

    public int getModelNo() {
        return modelNo;
    }

    public void setModelNo(int modelNo) {
        this.modelNo = modelNo;
    }

    public int getModelYear() {
        return modelYear;
    }

    public void setModelYear(int modelYear) {
        this.modelYear = modelYear;
    }

}

Comparador n. ° 1 basado en el modelo n.

public class CarModelNoCompartor implements Comparator<Car>{

    public int compare(Car o1, Car o2) {

        return o1.getModelNo() - o2.getModelNo();
    }

}

Comparador n. ° 2 basado en el año del modelo

public class CarModelYearComparator implements Comparator<Car> {

    public int compare(Car o1, Car o2) {

        return o1.getModelYear() - o2.getModelYear();
    }

}

Pero esto no es posible con el caso de la interfaz Comparable .

En el caso de la interfaz Comparable, solo podemos tener una lógica en el método compareTo () .

IamVickyAV
fuente
2

La relación del objeto que tiene este método y sus colaboradores es diferente.

compareTo()es un método de la interfaz Comparable , por lo que se utiliza para comparar ESTA instancia con otra.

compare()es un método de la interfaz Comparator , por lo que se utiliza para comparar dos instancias diferentes de otra clase entre sí.

Si lo desea, implementar Comparablesignifica que las instancias de la clase se pueden comparar fácilmente.
Implementar Comparatorsignifica que las instancias son adecuadas para comparar diferentes objetos (de otras clases).

Viejo
fuente
2

La principal diferencia está en el uso de las interfaces:

Comparable (que tiene compareTo ()) requiere que los objetos se comparen (para usar un TreeMap u ordenar una lista) para implementar esa interfaz. Pero, ¿qué pasa si la clase no implementa Comparable y no puede cambiarla porque es parte de una biblioteca de terceros? Luego tienes que implementar un Comparador, que es un poco menos conveniente de usar.

Michael Borgwardt
fuente
2

compareTo()se llama a un objeto, para compararlo con otro objeto. compare()se llama a algún objeto para comparar otros dos objetos.

La diferencia es donde se define la lógica que hace la comparación real.

Abgan
fuente
No es lo que yo llamaría una respuesta fantástica, pero no creo que merezca un voto negativo.
Paul Tomblin
De acuerdo, personalmente me reservo votos negativos para respuestas incorrectas o engañosas. Este es definitivamente correcto.
Joachim Sauer
Entonces, ¿dónde están esas personas "amigables" que me votaron negativamente? Esta es mi segunda respuesta correcta que fue rechazada porque alguien no entendió el punto. O el punto de votar en contra o el punto de mi respuesta. La vida es tan cruel ... ;-)
Abgan
0

Cuando desee ordenar una Lista que incluya el Objeto Foo, la clase Foo tiene que implementar la interfaz Comparable, porque el método de ordenación de la Lista utiliza este método.

Cuando desee escribir una clase Util que compare otras dos clases, puede implementar la clase Comparator.

Markus Lausberg
fuente
0


Nombre de la tabla de empleados , DoB, Salario
Tomas, 2/10/1982, 300
Daniel, 3/11/1990, 400
Kwame, 2/10/1998, 520

La interfaz Comparable le permite ordenar una lista de objetos, por ejemplo, Empleados con referencia a un campo principal; por ejemplo, puede ordenar por nombre o por salario con el método CompareTo ()

emp1.getName().compareTo(emp2.getName())

La interfaz Comparator proporciona una interfaz más flexible para tales requisitos , cuyo único método es compare ()

public interface Comparator<Employee> {
 int compare(Employee obj1, Employee obj2);
}

Código de muestra

public class NameComparator implements Comparator<Employee> {

public int compare(Employee e1, Employee e2) {
     // some conditions here
        return e1.getName().compareTo(e2.getName()); // returns 1 since (T)omas > (D)an 
    return e1.getSalary().compareTo(e2.getSalary()); // returns -1 since 400 > 300
}

}

karto
fuente
0

Un punto más:

  • compareTo()es de la Comparableinterfaz y compare()es de la Comparatorinterfaz.
  • Comparablese utiliza para definir un orden predeterminado para los objetos dentro de una clase, mientras que Comparatorse utiliza para definir un orden personalizado que se pasará a un método.
Premraj
fuente
0

Hay un aspecto técnico que también debe destacarse. Supongamos que necesita la parametrización del comportamiento de comparación de una clase de cliente y se pregunta si utilizar Comparableo Comparatorpara un método como este:

class Pokemon {
    int healthPoints;
    int attackDamage;
    public void battle (Comparable<Pokemon> comparable, Pokemon opponent) {
        if (comparable.compareTo(opponent) > 0) { //comparable needs to, but cannot, access this.healthPoints for example
            System.out.println("battle won");
        } else {
            System.out.println("battle lost");
        }
    }
}

comparablesería una lambda o un objeto, y no hay forma de comparableacceder a los campos de thisPokémon. (En una lambda, se thisrefiere a la instancia de clase externa en el alcance de la lambda, como se define en el texto del programa). Así que esto no vuela , y tenemos que usar a Comparatorcon dos argumentos.

flow2k
fuente
0

Utilice la interfaz Comparable para ordenar en función de más de un valor como edad, nombre, nombre de departamento ... Para un valor, utilice la interfaz Comparator

G.Brown
fuente
-2
Important Answar
String name;
int roll;

public int compare(Object obj1,Object obj2) { // For Comparator interface
    return obj1.compareTo(obj1);
}

public int compareTo(Object obj1) { // For Comparable Interface
    return obj1.compareTo(obj);
}

Aquí, en return obj1.compareTo(obj1)o return obj1.compareTo(obj)declaración, solo tome Object; primitivo no está permitido. Por ejemplo

name.compareTo(obj1.getName()) // Correct Statement.

Pero

roll.compareTo(obj1.getRoll()) 
// Wrong Statement Compile Time Error Because roll 
// is not an Object Type, it is primitive type.

El nombre es String Object, así que funcionó. Si desea ordenar el número de rollo de estudiantes, utilice el siguiente código.

public int compareTo(Object obj1) { // For Comparable Interface
    Student s = (Student) obj1;
    return rollno - s.getRollno();
}  

o

public int compare(Object obj1,Object obj2) { // For Comparator interface
    Student s1 = (Student) obj1;
    Student s2 = (Student) obj2;
    return s1.getRollno() - s2.getRollno();
}  
Bhabani Sankar Sahoo
fuente