Quando una classe dovrebbe essere comparabile e / o comparativa?


138

Ho visto classi che implementano sia Comparable che Comparator . Cosa significa questo? Perché dovrei usarne uno sopra l'altro?


18
Hai letto il javadoc su di loro? Descrive i diversi in modo abbastanza chiaro.
Skaffman,

1
Che cosa è comparabile e comparatore e quando usare comparabile e comparatore. Per conoscerli leggi questo link. questo ti aiuterà a capirne il comportamento e l'utilizzo. http://iandjava.blogspot.in/2012/10/comparable-and-comparator.html
RockStar

6
Questa è una buona domanda con una buona risposta obiettiva. Sono sgomento per il fatto che sia chiuso.
Russell Silva,

3
Altre domande su StackOverflow si riferiscono a questa come alla domanda definitiva "Qual è la differenza tra comparatore e comparabile". Perché è contrassegnato come "non costruttivo"? Come novizio di Java, questa è stata una domanda molto utile!
Pete,

Risposte:


241

Il testo seguente proviene da Comparator vs Comparable

paragonabile

Un oggetto comparabile è in grado di confrontarsi con un altro oggetto. La classe stessa deve implementare l' java.lang.Comparableinterfaccia per poter confrontare le sue istanze.

comparatore

Un oggetto comparatore è in grado di confrontare due diversi oggetti. La classe non sta confrontando le sue istanze, ma alcune istanze di altre classi. Questa classe di comparazione deve implementare l' java.util.Comparatorinterfaccia.


per una spiegazione dettagliata degli usi di Comparator e comparabili: sysdotoutdotprint.com/index.php/2017/03/28/…
mel3kings


@ mel3kings - Il collegamento non è più accessibile.
Gaurav,

152

Implementare Comparablesignifica " Posso confrontare me stesso con un altro oggetto " . Ciò è generalmente utile quando esiste un unico confronto predefinito naturale.

Implementare Comparatorsignifica " Sono in grado di confrontare altri due oggetti " . Ciò è in genere utile quando esistono più modi di confrontare due istanze di un tipo, ad esempio è possibile confrontare le persone per età, nome, ecc.


1
Ciao skeet, puoi per favore rilasciare il codice usando comparable e comparator.
Mdhar9e,

5
@ mdhar9e: ci sono molti esempi in giro - se hai difficoltà a tradurli nel tuo scenario specifico, fornisci maggiori informazioni in una nuova domanda.
Jon Skeet,

2
@alireza: ho già fatto un esempio nel secondo paragrafo: avendo comparatori diversi, puoi ordinare la stessa collezione (persone) per proprietà diverse (età, nome ecc.). Non puoi farlo semplicemente costruendo l' Personattrezzo Comparable, perché non puoi quindi cambiare il modo in cui due persone vengono confrontate.
Jon Skeet,

1
@feelgoodandprogramming: No, quelli sono algoritmi di ordinamento diversi . Esistono potenzialmente tre parti di codice qui, in tre diverse classi: 1) L'entità stessa, ad es Person. 2) Il comparatore, ad esempio PersonAgeComparatorche è in grado di confrontare due entità diverse e decidere quale dovrebbe venire prima in quel particolare ordinamento. 3) Il codice di ordinamento, che accetta una raccolta di entità e un comparatore, e ordina quella raccolta utilizzando il comparatore per determinare l'ordine.
Jon Skeet,

2
@RishiKeshPathak: Beh, è ​​più che usi Comparable se c'è solo una cosa ovvia su cui confrontare. E anche allora puoi semplicemente scrivere un comparatore. Se hai due programmi diversi che utilizzano la stessa classe e uno vuole ordinare solo per età e l'altro per nome, almeno uno di essi dovrà utilizzare un comparatore.
Jon Skeet,

38

Comparable consente a una classe di implementare il proprio confronto:

  • è nella stessa classe (spesso è un vantaggio)
  • può esserci una sola implementazione (quindi non puoi usarla se vuoi due casi diversi)

Per confronto, Comparator è un confronto esterno:

  • in genere si trova in un'istanza univoca (nella stessa classe o in un altro posto)
  • si nome ogni implementazione con il modo in cui si desidera ordinare le cose
  • puoi fornire comparatori per le classi che non controlli
  • l'implementazione è utilizzabile anche se il primo oggetto è null

In entrambe le implementazioni, puoi comunque scegliere ciò che desideri confrontare . Con generics, puoi dichiararlo e farlo controllare in fase di compilazione. Ciò migliora la sicurezza, ma è anche una sfida determinare il valore appropriato.

Come linea guida, generalmente utilizzo la classe o l'interfaccia più generale alla quale l'oggetto potrebbe essere confrontato, in tutti i casi d'uso che immagino ... Tuttavia, non una definizione molto precisa! :-(

  • Comparable<Object>ti permette di usarlo in tutti i codici in fase di compilazione (che è buono se necessario, o cattivo in caso contrario e perdi l'errore di compilazione); l'implementazione deve far fronte agli oggetti e lanciare secondo necessità, ma in modo robusto.
  • Comparable<Itself> è molto severo al contrario.

Divertente, quando si esegue la sottoclasse in sottoclasse, anche la sottoclasse deve essere comparabile ed essere solida (o infrangerebbe il principio di Liskov e ti darebbe errori di runtime).


20

java.lang.Comparable

  1. Per implementare l' Comparableinterfaccia, la classe deve implementare un singolo metodocompareTo()

    int a.compareTo(b)

  2. È necessario modificare la classe di cui si desidera ordinare l'istanza. In questo modo è possibile creare una sola sequenza di ordinamento per classe.

java.util.Comparator

  1. Per implementare l'interfaccia Comparator, la classe deve implementare un singolo metodo compare()

    int compare (a,b)

  2. Si crea una classe separata dalla classe di cui si desidera ordinare l'istanza. In questo modo è possibile creare più sequenze di ordinamento per classe.

14

Comparable serve per fornire un ordine predefinito su oggetti dati, ad esempio se gli oggetti dati hanno un ordine naturale.

A Comparatorrappresenta l'ordinamento stesso per un uso specifico.


8

Comparabledi solito è preferito. Ma a volte una classe implementa già Comparable, ma vuoi ordinare su una proprietà diversa. Quindi sei costretto a usare a Comparator.

Alcune classi in realtà prevedono Comparatorscasi comuni; per esempio, Stringper impostazione predefinita s sono sensibili al maiuscolo / minuscolo quando sono ordinati, ma esiste anche una Comparatorchiamata statica CASE_INSENSITIVE_ORDER.


7
Non sono sicuro di essere d'accordo sul fatto che Comparable sia preferito. Alcuni oggetti hanno un forte senso dell'ordine naturale, vale a dire i numeri, in tutte le loro forme: numeri naturali, numeri reali, date, ecc. Ma anche altri oggetti relativamente primitivi come le stringhe di caratteri mancano di un ordine universalmente applicabile. Nel caso di oggetti più complessi come un'entità da un modello di dominio dell'applicazione, l'implementazione di Comparable è di solito un errore. Le loro numerose proprietà rendono troppo difficile anticipare quale ordine sarà desiderato più spesso.
Erickson,

6

qui ci sono alcune differenze tra Comparator e Comparable che ho trovato sul web:

  1. Se vedi che la differenza logica tra questi due è Comparator in Java confronta due oggetti forniti a lui, mentre l'interfaccia Comparable confronta "questo" riferimento con l'oggetto specificato.

  2. Comparable in Java viene utilizzato per implementare l'ordinamento naturale dell'oggetto. In Java API String, le classi Date e wrapper implementano l'interfaccia Comparable.

  3. Se una classe implementa un'interfaccia comparabile in Java, la raccolta di quell'oggetto List o Array può essere ordinata automaticamente utilizzando il metodo Collections.sort () o Array.sort () e l'oggetto verrà ordinato in base all'ordine naturale definito dal metodo CompareTo.

  4. Gli oggetti che implementano Comparable in Java possono essere usati come chiavi in ​​una mappa ordinata o elementi in un set ordinato, ad esempio TreeSet, senza specificare alcun Comparatore.

sito: come utilizzare Comparator e Comparable in Java? Con esempio

Ulteriori informazioni: Come utilizzare Comparator e Comparable in Java? Con esempio


5

Comparableè per oggetti con un ordinamento naturale. L'oggetto stesso sa come deve essere ordinato.
Comparatorè per oggetti senza un ordine naturale o quando si desidera utilizzare un ordine diverso.


4

Differenza tra interfacce Comparator e Comparable

Comparable viene utilizzato per confrontarsi utilizzando un altro oggetto.

Comparator viene utilizzato per confrontare due tipi di dati sono oggetti.


2

Se vedi allora la differenza logica tra questi due è Comparatorin Java confrontare due oggetti forniti a lui, mentre l' Comparableinterfaccia confronta "questo" riferimento con l'oggetto specificato.

Comparablein Java viene utilizzato per implementare l'ordinamento naturale dell'oggetto. In Java API String, Date e classi wrapper implementano l' Comparableinterfaccia.

Se una qualsiasi classe implementa l' Comparableinterfaccia in Java, allora la raccolta di quell'oggetto Listo Arraypuò essere ordinata automaticamente usando Collections.sort()o Array.sort()metodo e l'oggetto verranno ordinati in base all'ordine naturale definito dacompareTo metodo.

Gli oggetti che implementano Comparablein Java possono essere utilizzati come chiavi in ​​una mappa ordinata o elementi in un set ordinato, ad esempio TreeSet, senza specificarne Comparator.


0

La mia libreria di annotazioni per l'implementazione di Comparable and 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);         
    }  
} 

Fai clic sul link per vedere altri esempi. compamatic


3
Benvenuto in StackOverflow. Questa domanda è vecchia e ha già ricevuto risposta. In genere, è meglio non resuscitare thread non aggiornati a meno che la risposta non fornisca qualcosa di significativamente nuovo o diverso rispetto alle risposte precedenti.
Il
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.