Qual é a diferença entre compare () e compareTo ()?

110

Qual é a diferença entre os métodos compare()e de Java compareTo()? Esses métodos dão a mesma resposta?

Pops
fonte
1
Qual método de comparação de classe você quer dizer?
Markus Lausberg
para uma explicação detalhada dos usos de compare () e compareTo (): sysdotoutdotprint.com/index.php/2017/03/28/…
mel3kings

Respostas:

160

De JavaNotes :

  • a.compareTo(b):
    Interface comparável: Compara valores e retorna um int que informa se os valores comparados são menores, iguais ou maiores que.
    Se seus objetos de classe têm uma ordem natural , implemente a Comparable<T>interface e defina este método. Todas as classes Java que têm uma ordenação natural implementar Comparable<T>- Exemplo: String, classes de mensagens publicitárias ,BigInteger

  • compare(a, b):
    Interface comparadora: Compara valores de dois objetos. Isso é implementado como parte da Comparator<T>interface e o uso típico é definir uma ou mais pequenas classes de utilitários que implementam isso, para passar para métodos como sort()ou para usar por ordenar estruturas de dados como TreeMapeTreeSet . Você pode querer criar um objeto Comparador para o seguinte:

    • Comparações múltiplas . Para fornecer várias maneiras diferentes de classificar algo. Por exemplo, você pode querer classificar uma classe Person por nome, ID, idade, altura, ... Você definiria um Comparador para cada um deles para passar para o sort()método.
    • Classe de sistema Para fornecer métodos de comparação para classes sobre as quais você não tem controle. Por exemplo, você pode definir um Comparador para Strings que os compare por comprimento.
    • Padrão de estratégia Para implementar um padrão de estratégia, que é uma situação em que você deseja representar um algoritmo como um objeto que você pode passar como um parâmetro, salvar em uma estrutura de dados, etc.

Se seus objetos de classe tiverem uma ordem de classificação natural, você pode não precisar de compare ().


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

Comparável
Um objeto comparável é capaz de se comparar a outro objeto.

Comparador
Um objeto comparador é capaz de comparar dois objetos diferentes. A classe não está comparando suas instâncias, mas as instâncias de algumas outras classes.


Contextos de caso de uso:

Interface comparável

O método equals ==e os != operadores e testam a igualdade / desigualdade, mas não fornecem uma maneira de testar os valores relativos .
Algumas classes (por exemplo, String e outras classes com uma ordem natural) implementam a Comparable<T>interface, que define um compareTo()método.
Você vai querer implementar Comparable<T>em sua classe se quiser usá-lo com os métodos Collections.sort()ou Arrays.sort().

Definindo um objeto Comparator

Você pode criar comparadores para classificar qualquer forma arbitrária para qualquer classe .
Por exemplo, a Stringclasse define o CASE_INSENSITIVE_ORDERcomparador .


A diferença entre as duas abordagens pode estar ligada à noção de:
Coleção Ordenada :

Quando uma coleção é ordenada, significa que você pode iterar na coleção em uma ordem específica (não aleatória) (a Hashtablenão está ordenada).

Uma coleção com uma ordem natural não é apenas ordenada, mas classificada . Definir uma ordem natural pode ser difícil! (como na ordem natural das cordas ).


Outra diferença, apontada por HaveAGuess nos comentários :

  • Comparable está na implementação e não é visível na interface, portanto, quando você classifica, não sabe realmente o que vai acontecer.
  • Comparator dá a você a garantia de que o pedido será bem definido.
VonC
fonte
2
Como essa resposta é exaustiva, aqui está algo que me irrita sobre o Comparable que você gostaria de adicionar: Ele está na implementação e não é visível na interface, portanto, quando você classifica, não sabe realmente o que vai acontecer. Usar um comparador dá a você a garantia de que a ordem será bem definida
HaveAGuess
@HaveAGuess bom ponto. Eu incluí seu comentário na resposta para mais visibilidade.
VonC
objetos têm uma ordem natural, o que ordem natural significa aqui? Um membro de dados de string para, por exemplo, nome na classe de funcionário tem ordem natural ??
Narendra Jaggi
@NarendraJaggi Consulte en.wikipedia.org/wiki/Enumeration . Uma ordem que facilita a enumeração. "Natural" no sentido de que uma determinada boa ordem no conjunto de índices fornece uma maneira única de listar o próximo elemento com uma enumeração parcial
VonC
2
@VedantKekan Obrigado. Eu restaurei 2 links nesta resposta.
VonC de
16

compareTo()é da Comparableinterface.

compare()é da Comparatorinterface.

Ambos os métodos fazem a mesma coisa, mas cada interface é usada em um contexto ligeiramente diferente.

A interface Comparable é usada para impor uma ordem natural aos objetos da classe de implementação. O compareTo()método é chamado de método de comparação natural. A interface Comparator é usada para impor uma ordem total aos objetos da classe de implementação. Para obter mais informações, consulte os links para saber exatamente quando usar cada interface.

Yuval Adam
fonte
você pode dar alguns exemplos? Ambos os métodos dão as mesmas respostas?
Não sei por que 'Comparável' é para ordenação natural. Podemos personalizá-lo, não podemos?
em
14

Semelhanças:
ambos são formas personalizadas de comparar dois objetos.
Ambos retornam uma intdescrição do relacionamento entre dois objetos.

Diferenças: o método compare()é um método que você é obrigado a implementar se implementar a Comparatorinterface. Ele permite que você passe dois objetos para o método e retorna um que intdescreve seu relacionamento.

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

O método compareTo()é um método que você é obrigado a implementar se implementar a Comparableinterface. Ele permite que um objeto seja comparado a objetos de tipo semelhante.

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

Resumo:
Basicamente, são duas maneiras diferentes de comparar as coisas.

jjnguy
fonte
9

Os métodos não precisam dar as mesmas respostas. Isso depende de quais objetos / classes você os chama.

Se você estiver implementando suas próprias classes que sabe que deseja comparar em algum estágio, pode solicitar que implementem a interface Comparable e o método compareTo () de acordo.

Se você estiver usando algumas classes de uma API que não implementa a interface Comparable, mas ainda assim deseja compará-las. Ou seja, para classificação. Você pode criar sua própria classe que implementa a interface Comparator e em seu método compare () você implementa a lógica.

Nicolai
fonte
3

A interface comparável contém um método chamado compareTo(obj)que leva apenas um argumento e se compara com outra instância ou objetos da mesma classe.

A interface de compare(obj1,obj2)comparação contém um método chamado que recebe dois argumentos e compara o valor de dois objetos da mesma classe ou de classes diferentes.

dilip kumar
fonte
3
compareTo(T object)

vem da interface java.lang.Comparable, implementada para comparar este objeto com outro para fornecer um valor int negativo para este objeto sendo menor que, 0 para igual ou valor positivo para maior que o outro. Este é o método de comparação mais conveniente, mas deve ser implementado em todas as classes que você deseja comparar.

compare(T obj1, T obj2)

vem da interface java.util.Comparator, implementada em uma classe separada que compara objetos de outra classe para fornecer um valor int negativo para o primeiro objeto sendo menor que, 0 para igual ou valor positivo para maior que o segundo objeto. É necessário quando você não pode fazer uma classe implementar compareTo () porque não é modificável. Também é usado quando você deseja maneiras diferentes de comparar objetos, não apenas um (como por nome ou idade).

godlovesdavid
fonte
3

Usando o Comparator, podemos ter n número de lógica de comparação escrita para uma classe .

Por exemplo

Para uma classe de carro

Podemos ter uma classe Comparator para comparar com base no número do modelo do carro. Também podemos ter uma classe de comparação para comparar com base no ano do modelo do carro.

Classe de carro

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 com base no modelo nº

public class CarModelNoCompartor implements Comparator<Car>{

    public int compare(Car o1, Car o2) {

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

}

Comparador nº 2 com base no ano do modelo

public class CarModelYearComparator implements Comparator<Car> {

    public int compare(Car o1, Car o2) {

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

}

Mas isso não é possível com o caso da interface Comparable .

No caso da interface Comparable, podemos ter apenas uma lógica no método compareTo () .

IamVickyAV
fonte
2

A relação do objeto com este método e seus colaboradores é diferente.

compareTo()é um método da interface Comparable , por isso é usado para comparar ESTA instância com outra.

compare()é um método da interface Comparator , portanto, é usado para comparar duas instâncias diferentes de outra classe entre si.

Se você quiser, implementar Comparablesignifica que as instâncias da classe podem ser facilmente comparadas.
Implementar Comparatorsignifica que as instâncias são adequadas para comparar objetos diferentes (de outras classes).

Ole
fonte
2

A principal diferença está no uso das interfaces:

Comparable (que tem compareTo ()) requer que os objetos sejam comparados (para usar um TreeMap ou para classificar uma lista) para implementar essa interface. Mas e se a classe não implementar Comparable e você não puder alterá-lo porque faz parte de uma biblioteca de terceiros? Em seguida, você deve implementar um Comparador, que é um pouco menos conveniente de usar.

Michael Borgwardt
fonte
2

compareTo()é chamado em um objeto, para compará-lo a outro objeto. compare()é chamado em algum objeto para comparar dois outros objetos.

A diferença é onde a lógica que faz a comparação real é definida.

Abgan
fonte
Não é o que eu chamaria de resposta fantástica, mas não acho que mereça um voto negativo.
Paul Tomblin
Concordo, pessoalmente reservo votos negativos para respostas erradas ou enganosas. Este é definitivamente correto.
Joachim Sauer
Então, onde estão essas pessoas 'amigáveis' que me rejeitaram? Esta é minha segunda resposta correta que foi rejeitada porque alguém não entendeu. Ou o ponto de downvoting ou o ponto de minha resposta. A vida é tão cruel ... ;-)
Abgan
0

Quando você deseja classificar uma List que inclui o Object Foo, a classe Foo deve implementar a interface Comparable, porque o método de classificação da List está usando esse método.

Quando você deseja escrever uma classe Util que compare duas outras classes, você pode implementar a classe Comparator.

Markus Lausberg
fonte
0


Nome da mesa do funcionário , DoB, Salário
Tomas, 2/10/1982, 300
Daniel, 3/11/1990, 400
Kwame, 2/10/1998, 520

A interface Comparable permite que você classifique uma lista de objetos, por exemplo, Funcionários com referência a um campo principal - por exemplo, você pode classificar por nome ou por salário com o método CompareTo ()

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

Uma interface mais flexível para tais requisitos é fornecida pelo interface Comparator , cujo único método é compare ()

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

Código de amostra

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
fonte
0

Mais um ponto:

  • compareTo()é da Comparableinterface e compare()é da Comparatorinterface.
  • Comparableé usado para definir uma ordem padrão para objetos dentro de uma classe, enquanto Comparatoré usado para definir uma ordem personalizada a ser passada para um método.
Premraj
fonte
0

Há um aspecto técnico que também deve ser enfatizado. Digamos que você precise de parametrização de comportamento de comparação de uma classe de cliente e está se perguntando se deve usar Comparableou Comparatorpara um 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");
        }
    }
}

comparableseria um lambda ou um objeto, e não há como comparableacessar os campos do thisPokémon. (Em um lambda, thisrefere-se à instância de classe externa no escopo do lambda, conforme definido no texto do programa.) Portanto, isso não funciona e temos que usar a Comparatorcom dois argumentos.

flow2k
fonte
0

Use a interface Comparable para classificar com base em mais de um valor, como age, name, dept_name ... Para um valor, use a interface Comparator

G.Brown
fonte
-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);
}

Aqui em return obj1.compareTo(obj1)ou return obj1.compareTo(obj)declaração apenas pegue Object; primitivo não é permitido. Por exemplo

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

Mas

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

nome é String Object, então funcionou. Se você quiser classificar o número do rolo de alunos, use o código abaixo.

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

ou

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
fonte