Qual è la differenza tra Java's compare() e compareTo()metodi? Questi metodi danno la stessa risposta?
Qual è la differenza tra Java's compare() e compareTo()metodi? Questi metodi danno la stessa risposta?
Risposte:
Da JavaNotes :
a.compareTo(b):
Interfaccia comparabile: confronta i valori e restituisce un int che indica se i valori sono inferiori, uguali o maggiori di.
Se gli oggetti della tua classe hanno un ordine naturale , implementa l' Comparable<T>interfaccia e definisci questo metodo. Tutte le classi Java che hanno un ordinamento naturale implementare Comparable<T>- ad esempio: String, classi wrapper ,BigInteger
compare(a, b):
Interfaccia di confronto : confronta i valori di due oggetti. Questo è implementato come parte Comparator<T>dell'interfaccia e l' uso tipico è quello di definire una o più piccole classi di utilità che lo implementano, per passare a metodi come sort()o per l'uso ordinando strutture di dati come TreeMapeTreeSet . Potresti voler creare un oggetto Comparator per quanto segue:
sort()metodo.Se gli oggetti della tua classe hanno un ordinamento naturale, potresti non aver bisogno di compare ().
Riepilogo da http://www.digizol.com/2008/07/java-sorting-comparator-vs-comparable.html
Comparabile
Un oggetto comparabile è in grado di confrontarsi con un altro oggetto.
Comparatore
Un oggetto comparatore è in grado di confrontare due oggetti diversi. La classe non confronta le sue istanze, ma le istanze di un'altra classe.
Contesti dei casi d'uso:
Interfaccia comparabile
Il metodo uguale e ==e!= operatori verificano l'uguaglianza / disuguaglianza, ma non forniscono un modo per verificare i valori relativi .
Alcune classi (ad esempio, String e altre classi con un ordinamento naturale) implementano l' Comparable<T>interfaccia, che definisce un compareTo()metodo.
Dovrai implementarlo Comparable<T>nella tua classe se vuoi usarlo con i metodi Collections.sort()o Arrays.sort().
Definizione di un oggetto Comparator
Puoi creare comparatori per ordinare qualsiasi modo arbitrario per qualsiasi classe .
Ad esempio, la Stringclasse definisce il CASE_INSENSITIVE_ORDERcomparatore .
La differenza tra i due approcci può essere collegata alla nozione di:
Raccolta ordinata :
Quando una raccolta viene ordinata, significa che è possibile iterare nella raccolta in un ordine specifico (non casuale) (a Hashtablenon è ordinato).
Una collezione con un ordine naturale non è solo ordinata, ma ordinata . Definire un ordine naturale può essere difficile! (come nell'ordine delle corde naturale ).
Un'altra differenza, sottolineata da HaveAGuess nei commenti :
Comparable è nell'implementazione e non è visibile dall'interfaccia, quindi quando esegui l'ordinamento non sai davvero cosa succederà. Comparator ti rassicura che l'ordine sarà ben definito. compareTo()è Comparabledall'interfaccia.
compare()è Comparatordall'interfaccia.
Entrambi i metodi fanno la stessa cosa, ma ogni interfaccia viene utilizzata in un contesto leggermente diverso.
L' interfaccia Comparable viene utilizzata per imporre un ordinamento naturale agli oggetti della classe di implementazione. Il compareTo()metodo è chiamato metodo di confronto naturale. L' interfaccia Comparator viene utilizzata per imporre un ordinamento totale sugli oggetti della classe di implementazione. Per ulteriori informazioni, vedere i collegamenti per sapere esattamente quando utilizzare ciascuna interfaccia.
Somiglianze:
entrambi sono modi personalizzati per confrontare due oggetti.
Entrambi restituiscono una intdescrizione della relazione tra due oggetti.
Differenze:
il metodo compare()è un metodo che sei obbligato a implementare se implementi l' Comparatorinterfaccia. Ti consente di passare due oggetti nel metodo e restituisce una intdescrizione della loro relazione.
Comparator comp = new MyComparator();
int result = comp.compare(object1, object2);
Il metodo compareTo()è un metodo che sei obbligato a implementare se implementi l' Comparableinterfaccia. Consente di confrontare un oggetto con oggetti di tipo simile.
String s = "hi";
int result = s.compareTo("bye");
Riepilogo:
fondamentalmente sono due modi diversi per confrontare le cose.
I metodi non devono dare le stesse risposte. Dipende da quali oggetti / classi li chiami.
Se stai implementando le tue classi che sai di voler confrontare a un certo punto, potresti fare in modo che implementino l'interfaccia Comparable e implementino il metodo compareTo () di conseguenza.
Se stai utilizzando alcune classi di un'API che non implementano l'interfaccia Comparable, ma desideri comunque confrontarle. Cioè per l'ordinamento. Puoi creare la tua classe che implementa l'interfaccia di Comparator e nel suo metodo compare () implementare la logica.
L' interfaccia comparabile contiene un metodo chiamato compareTo(obj)che accetta solo un argomento e si confronta con un'altra istanza o oggetti della stessa classe.
L' interfaccia del comparatore contiene un metodo chiamato compare(obj1,obj2)che accetta due argomenti e confronta il valore di due oggetti della stessa classe o di classi diverse.
compareTo(T object)
proviene dall'interfaccia java.lang.Comparable, implementata per confrontare questo oggetto con un altro per fornire un valore int negativo per questo oggetto inferiore a, 0 per uguale o positivo per maggiore dell'altro. Questo è il metodo di confronto più conveniente, ma deve essere implementato in ogni classe che si desidera confrontare.
compare(T obj1, T obj2)
proviene dall'interfaccia java.util.Comparator, implementata in una classe separata che confronta gli oggetti di un'altra classe per fornire un valore int negativo per il primo oggetto minore di, 0 per uguale o un valore positivo per maggiore del secondo oggetto. È necessario quando non è possibile fare in modo che una classe implementi compareTo () perché non è modificabile. Viene anche utilizzato quando si desiderano modi diversi per confrontare gli oggetti, non solo uno (ad esempio per nome o età).
Usando Comparator, possiamo avere n numero di logica di confronto scritta per una classe .
Per esempio
Per una classe di auto
Possiamo avere una classe di confronto da confrontare in base al numero di modello dell'auto. Possiamo anche avere una classe di confronto da confrontare in base all'anno del modello dell'auto.
Classe di auto
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;
}
}
Comparatore n. 1 basato sul modello n
public class CarModelNoCompartor implements Comparator<Car>{
public int compare(Car o1, Car o2) {
return o1.getModelNo() - o2.getModelNo();
}
}
Comparatore n. 2 basato sull'anno del modello
public class CarModelYearComparator implements Comparator<Car> {
public int compare(Car o1, Car o2) {
return o1.getModelYear() - o2.getModelYear();
}
}
Ma questo non è possibile con il caso di Comparable .
In caso di interfaccia Comparable, possiamo avere una sola logica nel metodo compareTo () .
Il rapporto dell'oggetto che ha questo metodo e dei suoi collaboratori è diverso.
compareTo()è un metodo dell'interfaccia Comparable , quindi viene utilizzato per confrontare QUESTA istanza con un'altra.
compare()è un metodo dell'interfaccia Comparator , quindi viene utilizzato per confrontare tra loro due diverse istanze di un'altra classe.
Se vuoi, l'implementazione Comparablesignifica che le istanze della classe possono essere facilmente confrontate.
L'implementazione Comparatorsignifica che le istanze sono adatte per confrontare oggetti diversi (di altre classi).
La differenza principale è nell'uso delle interfacce:
Comparable (che ha compareTo ()) richiede che gli oggetti vengano confrontati (per utilizzare una TreeMap o per ordinare un elenco) per implementare quell'interfaccia. Ma cosa succede se la classe non implementa Comparable e non è possibile modificarla perché fa parte di una libreria di terze parti? Quindi devi implementare un comparatore, che è un po 'meno comodo da usare.
compareTo()viene chiamato su un oggetto, per confrontarlo con un altro oggetto.
compare()viene chiamato su un oggetto per confrontare altri due oggetti.
La differenza è dove viene definita la logica che esegue il confronto effettivo.
Quando si desidera ordinare un List che include l'Object Foo, la classe Foo deve implementare l'interfaccia Comparable, perché il metodo di ordinamento della List utilizza questo metodo.
Quando si desidera scrivere una classe Util che confronta altre due classi, è possibile implementare la classe Comparator.
Nome tabella dipendenti , DoB, Salary
Tomas, 2/10/1982, 300
Daniel, 3/11/1990, 400
Kwame, 2/10/1998, 520
L' interfaccia Comparable ti consente di ordinare un elenco di oggetti ad es. Dipendenti con riferimento a un campo principale - ad esempio, puoi ordinare per nome o per stipendio con il metodo CompareTo ()
emp1.getName().compareTo(emp2.getName())
Un'interfaccia più flessibile per tali requisiti è fornita dall'interfaccia Comparator , il cui unico metodo è compare ()
public interface Comparator<Employee> {
int compare(Employee obj1, Employee obj2);
}
Codice di esempio
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
}
}
Un altro punto:
compareTo()proviene Comparabledall'interfaccia e compare()proviene Comparatordall'interfaccia.Comparableviene utilizzato per definire un ordinamento predefinito per gli oggetti all'interno di una classe mentre Comparatorviene utilizzato per definire un ordinamento personalizzato da passare a un metodo.C'è anche un aspetto tecnico che dovrebbe essere sottolineato. Supponi di aver bisogno della parametrizzazione del comportamento di confronto da una classe client e ti stai chiedendo se utilizzare Comparableo Comparatorper un metodo come questo:
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");
}
}
}
comparablesarebbe un lambda o un oggetto, e non c'è modo comparabledi accedere ai campi di thisPokemon. (In un lambda, si thisriferisce all'istanza della classe esterna nell'ambito del lambda, come definito nel testo del programma.) Quindi questo non funziona e dobbiamo usare a Comparatorcon due argomenti.
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);
}
Qui in return obj1.compareTo(obj1)o return obj1.compareTo(obj)dichiarazione prendi solo Object; primitiva non è consentita. Per esempio
name.compareTo(obj1.getName()) // Correct Statement.
Ma
roll.compareTo(obj1.getRoll())
// Wrong Statement Compile Time Error Because roll
// is not an Object Type, it is primitive type.
name è String Object quindi ha funzionato. Se vuoi ordinare il numero del rotolo di studenti, usa il codice sottostante.
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();
}