Quando uma classe deve ser comparável e / ou comparadora?

138

Eu já vi classes que implementam o Comparable e o Comparator . O que isto significa? Por que eu usaria um sobre o outro?

Nick Heiner
fonte
18
Você leu o javadoc sobre eles? Descreve o diferente claramente.
22410 skaffman
1
O que é comparável e comparador e quando usar comparável e comparador. Para conhecê-los, leia este link. isso ajudará você a entender o comportamento e o uso deles. http://iandjava.blogspot.in/2012/10/comparable-and-comparator.html
RockStar
6
Esta é uma boa pergunta com uma resposta boa e objetiva. Estou consternado por estar fechado.
Russell Silva
3
Outras perguntas no StackOverflow se referem a isso como a pergunta definitiva "Qual é a diferença entre comparador e comparável". Por que está marcado como "não construtivo"? Como um novato em Java, essa foi uma pergunta muito útil!
Pete

Respostas:

241

O texto abaixo é de Comparador x Comparável

Comparável

Um objeto comparável é capaz de se comparar com outro objeto. A própria classe deve implementar a java.lang.Comparableinterface para poder comparar suas instâncias.

Comparador

Um objeto comparador é capaz de comparar dois objetos diferentes. A classe não está comparando suas instâncias, mas algumas instâncias de outras classes. Essa classe comparadora deve implementar a java.util.Comparatorinterface.

Dan
fonte
para explicação detalhada dos usos de ambos Comparador e comparáveis: sysdotoutdotprint.com/index.php/2017/03/28/...
mel3kings
@ mel3kings - O link não está mais acessível.
Gaurav #
152

Implementar Comparablesignifica " Eu posso me comparar com outro objeto " . Isso geralmente é útil quando há uma única comparação padrão natural.

Implementar Comparatorsignifica " Eu posso comparar dois outros objetos " . Isso geralmente é útil quando existem várias maneiras de comparar duas instâncias de um tipo - por exemplo, você pode comparar pessoas por idade, nome etc.

Jon Skeet
fonte
1
Olá skeet, você pode largar o código usando comparável e comparador.
Mdhar9e
5
@ mdhar9e: Existem muitos exemplos por aí - se você estiver tendo dificuldades para traduzi-los em seu cenário específico, forneça mais informações em uma nova pergunta.
Jon Skeet
2
@ alireza: Eu já dei um exemplo no segundo parágrafo: por ter comparadores diferentes, você pode classificar a mesma coleção (pessoas) por propriedades diferentes (idade, nome etc.). Você não pode fazer isso apenas Personimplementando Comparable, porque não pode mudar como duas pessoas são comparadas.
Jon Skeet
1
@feelgoodandprogramming: Não, esses são algoritmos de classificação diferentes . Existem potencialmente três partes de código aqui, em três classes diferentes: 1) A própria entidade, por exemplo Person. 2) O comparador, por exemplo, PersonAgeComparatorque é capaz de comparar duas entidades diferentes e decidir quais devem vir em primeiro lugar nessa ordem de classificação específica. 3) O código de classificação, que pega uma coleção de entidades e um comparador e classifica essa coleção usando o comparador para determinar a ordem.
11134 Jon Skeet
2
@RishiKeshPathak: Bem, é mais que você use Comparable se houver apenas uma coisa óbvia para comparar. E mesmo assim você pode escrever um comparador. Se você tiver dois programas diferentes usando a mesma classe, e um quiser classificar apenas por idade e o outro apenas por nome, pelo menos um deles precisará usar um Comparador.
Jon Skeet
38

Comparable permite que uma classe implemente sua própria comparação:

  • está na mesma classe (geralmente é uma vantagem)
  • pode haver apenas uma implementação (então você não pode usá-la se quiser dois casos diferentes)

Por comparação, o Comparator é uma comparação externa:

  • normalmente está em uma instância exclusiva (na mesma classe ou em outro local)
  • você nomeia cada implementação da maneira que deseja classificar
  • você pode fornecer comparadores para classes que você não controla
  • a implementação é utilizável mesmo se o primeiro objeto for nulo

Nas duas implementações, você ainda pode escolher o que deseja comparar . Com os genéricos, você pode declarar isso e verificá-lo no momento da compilação. Isso melhora a segurança, mas também é um desafio determinar o valor apropriado.

Como orientação, geralmente uso a classe ou interface mais geral com a qual esse objeto pode ser comparado, em todos os casos de uso que imagino ... Uma definição não muito precisa! :-(

  • Comparable<Object>permite usá-lo em todos os códigos em tempo de compilação (o que é bom, se necessário, ou ruim, se não, e você perde o erro em tempo de compilação); sua implementação precisa lidar com objetos e transmitir conforme necessário, mas de maneira robusta.
  • Comparable<Itself> é muito rigoroso, pelo contrário.

Engraçado, quando você se subclassifica em subclasse, a subclasse também deve ser comparável e ser robusta quanto a isso (ou isso violaria o princípio de Liskov e causaria erros de tempo de execução).

KLE
fonte
20

java.lang.Comparable

  1. Para implementar a Comparableinterface, a classe deve implementar um único métodocompareTo()

    int a.compareTo(b)

  2. Você deve modificar a classe cuja instância você deseja classificar. Para que apenas uma sequência de classificação possa ser criada por classe.

java.util.Comparator

  1. Para implementar a interface Comparator, a classe deve implementar um único método compare()

    int compare (a,b)

  2. Você constrói uma classe separada da classe cuja instância você deseja classificar. Para que a sequência de classificação múltipla possa ser criada por classe.
codiacTushki
fonte
14

Comparable é para fornecer uma ordem padrão para objetos de dados, por exemplo, se os objetos de dados tiverem uma ordem natural.

A Comparatorrepresenta a própria ordem para um uso específico.

starblue
fonte
8

Comparableé geralmente preferido. Mas, às vezes, uma classe já é implementada Comparable, mas você deseja classificar em uma propriedade diferente. Então você é forçado a usar um Comparator.

Algumas classes realmente fornecem Comparatorscasos comuns; por exemplo, Strings diferenciam maiúsculas de minúsculas quando classificados, mas também há uma estática Comparatorchamada CASE_INSENSITIVE_ORDER.

Michael Myers
fonte
7
Não tenho certeza se concordo com o Comparable sendo o preferido. Alguns objetos têm um forte senso de ordem natural - ou seja, números, em todas as suas formas: números naturais, números reais, datas, etc. Mas até outros objetos relativamente primitivos, como cadeias de caracteres, não têm uma ordem universalmente aplicável. No caso de objetos mais complexos, como uma entidade, de um modelo de domínio de aplicativo, implementar Comparable geralmente é um erro. Suas muitas propriedades tornam muito difícil prever qual ordem será desejada com mais frequência.
21411 erickson
6

Aqui estão algumas diferenças entre o comparador e o comparável que encontrei na web:

  1. Se você perceber que a diferença lógica entre esses dois é o Comparator em Java, compare dois objetos fornecidos a ele, enquanto a interface Comparable compara a referência "this" com o objeto especificado.

  2. Comparável em Java é usado para implementar a ordenação natural do objeto. Na Java API String, as classes Date e wrapper implementam a interface Comparable.

  3. Se alguma classe implementar a interface Comparable em Java, a coleção desse objeto List ou Array poderá ser classificada automaticamente usando o método Collections.sort () ou Array.sort () e o objeto será classificado com base na ordem natural definida pelo método CompareTo.

  4. Objetos que implementam Comparable em Java podem ser usados ​​como chaves em um mapa classificado ou em elementos em um conjunto classificado, por exemplo, TreeSet, sem especificar nenhum Comparador.

site: Como usar o Comparator e o Comparable em Java? Com exemplo

Leia mais: Como usar o Comparator e o Comparable em Java? Com exemplo

javapassion
fonte
5

Comparableé para objetos com uma ordem natural. O próprio objeto sabe como deve ser pedido.
Comparatoré para objetos sem uma ordem natural ou quando você deseja usar uma ordem diferente.

Michael Lloyd Lee mlk
fonte
4

Diferença entre as interfaces Comparador e Comparável

Comparable é usado para se comparar usando outro objeto.

Comparator é usado para comparar dois tipos de dados são objetos.

SravaniChowdary.Gorijavolu
fonte
2

Se você perceber que a diferença lógica entre esses dois está Comparatorem Java, compare dois objetos fornecidos a ele, enquanto a Comparableinterface compara a referência "this" com o objeto especificado.

Comparableem Java é usado para implementar a ordenação natural do objeto. Na Java API String, as classes Date e wrapper implementam a Comparableinterface.

Se alguma classe implementar Comparableinterface em Java, a coleção desse objeto será Listou Arraypoderá ser classificada automaticamente usando o método Collections.sort()ou Array.sort(), e o objeto será classificado com base na ordem natural definida pelo compareTométodo.

Objetos implementados Comparableem Java podem ser usados ​​como chaves em um mapa classificado ou elementos em um conjunto classificado, por exemplo TreeSet, sem especificar nenhum Comparator.

Srinivas
fonte
0

Minha anotação lib para implementar Comparable e 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);         
    }  
} 

Clique no link para ver mais exemplos. compamatic

Jianmin Liu
fonte
3
Bem-vindo ao stackoverflow. Esta pergunta é antiga e já foi respondida. Normalmente, é melhor não ressuscitar threads obsoletos, a menos que sua resposta contribua com algo significativamente novo ou diferente das respostas anteriores.
Oers