Compare () ve CompareTo () arasındaki fark nedir?


Yanıtlar:


160

Gönderen JavaNotes :

  • a.compareTo(b):
    Karşılaştırılabilir arayüz: Değerleri karşılaştırır ve değerlerin daha küçük, eşit veya daha büyük olup olmadığını söyleyen bir int döndürür.
    Sınıf nesnelerinizin doğal bir sırası varsa , Comparable<T>arabirimi uygulayın ve bu yöntemi tanımlayın. Doğal bir sipariş uygulamak gereken tek şey Java sınıfları Comparable<T>- Örnek: String, sarıcı sınıflar ,BigInteger

  • compare(a, b):
    Karşılaştırıcı arayüzü: İki nesnenin değerlerini karşılaştırır. Bu bir parçası olarak uygulanmaktadır Comparator<T>arayüzü ve tipik kullanım gibi yöntemlere geçmek için, bu uygulama, bir ya da daha fazla küçük yardımcı uygulama sınıflarını tanımlamak için sort()ya da veri yapıları sıralama tarafından kullanılmak üzere TreeMapveTreeSet . Aşağıdakiler için bir Comparator nesnesi oluşturmak isteyebilirsiniz:

    • Çoklu karşılaştırmalar . Bir şeyi sıralamak için birkaç farklı yol sağlamak. Örneğin, bir Kişi sınıfını ada, kimliğe, yaşa, yüksekliğe, ... göre sıralamak isteyebilirsiniz. Bunların her birinin sort()yönteme geçmesi için bir Karşılaştırıcı tanımlayabilirsiniz .
    • Sistem sınıfı Üzerinde kontrolünüz olmayan sınıflar için karşılaştırma yöntemleri sağlamak için. Örneğin, Dizeler için uzunluklarına göre karşılaştıran bir Karşılaştırıcı tanımlayabilirsiniz.
    • Strateji modeli Bir algoritmayı parametre olarak iletebileceğiniz, veri yapısına kaydedebileceğiniz vb. Bir nesne olarak temsil etmek istediğiniz bir durum olan Strateji modelini uygulamak için.

Sınıf nesnelerinizin bir doğal sıralama düzeni varsa, Compare () 'e ihtiyacınız olmayabilir.


Http://www.digizol.com/2008/07/java-sorting-comparator-vs-comparable.html adresinden özet

Karşılaştırılabilir Kıyaslanabilir
bir nesne, kendisini başka bir nesneyle karşılaştırma yeteneğine sahiptir.

Karşılaştırıcı
Bir karşılaştırıcı nesne, iki farklı nesneyi karşılaştırabilir. Sınıf, örneklerini değil, başka bir sınıfın örneklerini karşılaştırıyor.


Kullanım durumu bağlamları:

Karşılaştırılabilir arayüz

Yöntemi ve eşit ==ve != operatörler eşitlik / eşitsizlik için testi, ancak göreceli değerler için test etmek için bir yol vermeyin .
Bazı sınıflar (örneğin, String ve doğal sıralamaya sahip diğer sınıflar) Comparable<T>bir compareTo()yöntemi tanımlayan arabirimi uygular . Veya yöntemleriyle kullanmak istiyorsanız sınıfınızda
uygulamak Comparable<T>isteyeceksiniz .Collections.sort()Arrays.sort()

Bir Comparator nesnesi tanımlama

Herhangi bir sınıf için herhangi bir rasgele şekilde sıralamak için Karşılaştırıcılar oluşturabilirsiniz .
Örneğin, Stringsınıf CASE_INSENSITIVE_ORDERkarşılaştırıcıyı tanımlar .


İki yaklaşım arasındaki fark şu kavramla ilişkilendirilebilir:
Sıralı Koleksiyon :

Bir Koleksiyon sipariş edildiğinde, koleksiyonda belirli (rastgele olmayan) bir sırada (a Hashtablesıralanmamış) yineleme yapabileceğiniz anlamına gelir .

Doğal bir sıraya sahip bir Koleksiyon sadece sıralanmaz, aynı zamanda sıralanır . Doğal bir düzen tanımlamak zor olabilir! ( doğal String düzeninde olduğu gibi ).


Diğer bir farklılık, tarafından işaret HaveAGuess içinde yorumlarla :

  • Comparable uygulama aşamasındadır ve arayüzden görünmez, bu nedenle sıraladığınızda ne olacağını gerçekten bilemezsiniz.
  • Comparator siparişin iyi tanımlanacağına dair size güvence verir.

2
Bu cevap kapsamlı olduğundan, burada, Comparable hakkında beni rahatsız eden bir şey eklemek isteyebilirsiniz: Bu, uygulamada ve arayüzden görünmüyor, bu yüzden sıraladığınızda ne olacağını gerçekten bilmiyorsunuz. Bir karşılaştırıcı kullanmak, siparişin iyi tanımlanacağına dair size güvence verir
HaveAGuess

@HaveAGuess iyi bir nokta. Daha fazla görünürlük için yorumunuzu cevaba ekledim.
VonC

nesnelerin doğal bir düzeni var, burada doğal düzen ne anlama geliyor? Örneğin, çalışan sınıfındaki ad için bir dize veri üyesi doğal bir sıraya sahip mi?
Narendra Jaggi

@NarendraJaggi bakınız en.wikipedia.org/wiki/Enumeration . Numaralandırmayı kolaylaştıran bir düzen. Dizin kümesindeki belirli bir iyi sıralamanın, kısmi numaralandırma verilen bir sonraki öğeyi listelemek için benzersiz bir yol sağlaması anlamında "Doğal"
VonC

2
@VedantKekan Teşekkürler. Bu cevapta 2 bağlantıyı geri yükledim.
VonC

16

compareTo()dan Comparablearayüz.

compare()dan Comparatorarayüz.

Her iki yöntem de aynı şeyi yapar, ancak her arayüz biraz farklı bir bağlamda kullanılır.

Karşılaştırılabilir arayüzü uygulayan sınıfın nesneler üzerinde doğal bir sıralamayı empoze etmek için kullanılır. compareTo()Yöntem, doğal karşılaştırma yöntemi olarak adlandırılır. Karşılaştırıcı arayüzü uygulayan sınıfın nesneler üzerinde toplam sipariş empoze etmek için kullanılır. Daha fazla bilgi için, her bir arabirimin tam olarak ne zaman kullanılacağına ilişkin bağlantılara bakın.


Bazı örnekler verebilir misiniz? Her iki yöntem de aynı cevapları verir?

Neden "Kıyaslanabilir" in doğal sipariş için olduğunu bilmiyorum? Onu özelleştirebiliriz, değil mi?
c-an

14

Benzerlikler:
Her ikisi de, iki nesneyi karşılaştırmanın özel yollarıdır.
Her ikisi de intiki nesne arasındaki ilişkiyi açıklayan bir döndürür .

Farklar: Yöntem compare(), Comparatorarayüzü uygularsanız uygulamak zorunda olduğunuz bir yöntemdir . Yönteme iki nesne aktarmanıza izin verir intve ilişkilerini açıklayan bir döndürür .

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

Yöntem compareTo(), Comparablearayüzü uygularsanız uygulamak zorunda olduğunuz bir yöntemdir . Bir nesnenin benzer türdeki nesnelerle karşılaştırılmasına izin verir.

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

Özet:
Temelde, şeyleri karşılaştırmanın iki farklı yolu.


9

Yöntemlerin aynı cevapları vermesi gerekmez. Bu, onları hangi nesnelere / sınıflara çağırdığınıza bağlıdır.

Bir aşamada karşılaştırmak istediğinizi bildiğiniz kendi sınıflarınızı uyguluyorsanız, bu sınıfların Comparable arabirimini uygulamalarını ve buna göre CompareTo () yöntemini uygulamalarını sağlayabilirsiniz.

Karşılaştırılabilir arabirimi uygulamayan bir API'den bazı sınıflar kullanıyorsanız, ancak yine de bunları karşılaştırmak istiyorsanız. Yani sıralamak için. Comparator arabirimini uygulayan kendi sınıfınızı yaratabilir ve onun Compare () yönteminde mantığı uygulayabilirsiniz.


3

Karşılaştırılabilir arayüz, compareTo(obj)yalnızca bir argüman alan ve kendisini aynı sınıfın başka bir örneği veya nesneleriyle karşılaştıran bir yöntem içerir .

Karşılaştırıcı arabirimi, compare(obj1,obj2)iki argüman alan ve aynı veya farklı sınıflardan iki nesnenin değerini karşılaştıran bir yöntem içerir .


3
compareTo(T object)

java.lang.Comparable arabiriminden gelir, bu nesneyi başka bir nesneyle karşılaştırmak için uygulanan bu nesneye eşittir için 0'dan küçük veya diğerinden daha büyük pozitif değer için negatif bir int değeri verir. Bu daha uygun karşılaştırma yöntemidir, ancak karşılaştırmak istediğiniz her sınıfta uygulanmalıdır.

compare(T obj1, T obj2)

java.util.Comparator arabiriminden gelir, başka bir sınıfın nesnelerini karşılaştırarak birinci nesnenin negatif int değeri, eşittir için 0 veya ikinci nesneden daha büyük pozitif değer verecek şekilde karşılaştırıldığı ayrı bir sınıfta uygulanır. Değiştirilebilir olmadığından, bir sınıf uygulaması CompareTo () yapamadığınızda gereklidir. Ayrıca, nesneleri karşılaştırmak için yalnızca birini değil (ad veya yaş gibi) farklı yöntemler istediğinizde de kullanılır.


3

Comparator kullanarak, bir sınıf için yazılmış n sayıda karşılaştırma mantığına sahip olabiliriz .

Örneğin

Araba Sınıfı İçin

Araba model numarasına göre karşılaştırmak için bir Karşılaştırıcı sınıfımız olabilir. Otomobil model yılına göre karşılaştırmak için bir Karşılaştırıcı sınıfımız da olabilir.

Araba Sınıfı

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;
    }

}

Model No'ya göre karşılaştırıcı # 1

public class CarModelNoCompartor implements Comparator<Car>{

    public int compare(Car o1, Car o2) {

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

}

Model Yılına göre Karşılaştırıcı # 2

public class CarModelYearComparator implements Comparator<Car> {

    public int compare(Car o1, Car o2) {

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

}

Ancak Karşılaştırılabilir arayüz durumunda bu mümkün değildir .

Comparable arabirim durumunda, ComparTo () yönteminde yalnızca bir mantığımız olabilir .


2

Bu yönteme sahip nesnenin ve işbirlikçilerinin ilişkisi farklıdır.

compareTo()Karşılaştırılabilir arayüzün bir yöntemidir , bu nedenle BU örneğini başka bir örnekle karşılaştırmak için kullanılır.

compare()Comparator arabiriminin bir yöntemidir , bu nedenle başka bir sınıfın iki farklı örneğini birbiriyle karşılaştırmak için kullanılır.

İsterseniz, uygulama Comparable, sınıfın örneklerinin kolayca karşılaştırılabileceği anlamına gelir.
Uygulama Comparator, örneklerin (diğer sınıflardan) farklı nesneleri karşılaştırmaya uygun olduğu anlamına gelir.


2

Temel fark, arayüzlerin kullanımında:

Comparable (ComparTo () özelliğine sahip), bu arabirimi uygulamak için nesnelerin karşılaştırılmasını (bir Ağaç Haritası kullanmak veya bir listeyi sıralamak için) gerektirir. Peki ya sınıf Comparable uygulamazsa ve 3. taraf kitaplığının parçası olduğu için onu değiştiremezseniz? Daha sonra, kullanımı biraz daha az uygun olan bir Karşılaştırıcı uygulamanız gerekir.


2

compareTo()bir nesneyi başka bir nesneyle karşılaştırmak için çağrılır. compare()diğer iki nesneyi karşılaştırmak için bir nesneye çağrılır.

Fark, gerçek karşılaştırmayı yapan mantığın tanımlandığı yerdir.


Harika bir cevap diyeceğim şey değil, ama olumsuz bir oyu hak ettiğini düşünmüyorum.
Paul Tomblin

Kabul ediyorum, şahsen yanlış veya yanıltıcı cevaplar için olumsuz oyları saklıyorum. Bu kesinlikle doğru.
Joachim Sauer

Öyleyse beni reddeden 'dost canlısı' insanlar nerede? Bu, birisi noktayı kaçırdığı için olumsuz oy verilen ikinci doğru cevabım. Ya olumsuz oylama ya da cevabımın amacı. Hayat çok acımasız .. ;-)
Abgan

0

Object Foo içeren bir Listeyi sıralamak istediğinizde, Foo sınıfının Comparable arabirimini uygulaması gerekir, çünkü List'in sıralama yöntemi bu yöntemi kullanır.

Diğer iki sınıfı karşılaştıran bir Util sınıfı yazmak istediğinizde, Comparator sınıfını uygulayabilirsiniz.


0

Çalışan Tablo
Adı, DoB, Maaş
Tomas, 2/10/1982, 300
Daniel, 3/11/1990, 400
Kwame, 2/10/1998, 520

Karşılaştırmalı adıyla sıralama olabilir veya maaş, örneğin - arayüzü bir birincil alan referansla nesnelerin, örneğin Çalışan bir listesini sıralamak sağlar CompareTo () metodu

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

Bu tür gereksinimler için daha esnek bir arabirim , tek yöntemi Compar () olan Comparator arabirimi tarafından sağlanır.

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

Basit kod

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
}

}


0

Bir nokta daha:

  • compareTo()ila Comparablearayüzü ve compare()ila Comparatorarayüz.
  • Comparablebir sınıftaki nesneler için varsayılan bir sıralama tanımlamak için Comparatorkullanılırken, bir yönteme iletilecek özel bir sıralamayı tanımlamak için kullanılır.

0

Vurgulanması gereken teknik bir yönü de var. Bir istemci sınıftan karşılaştırma davranış parametreleştirilmesini gerekir ve kullanılıp kullanılmayacağını merak ediyor Say Comparableveya Comparatorböyle bir yöntem:

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");
        }
    }
}

comparablebir lambda veya bir nesne olur ve Pokemon'un comparablealanlarına erişmenin bir yolu yoktur this. (Bir lambda'da, thisprogram metninde tanımlandığı gibi lambda kapsamındaki dış sınıf örneğini ifade eder.) Yani bu uçmaz ve Comparatoriki argümanlı a kullanmalıyız .


0

Age, name, dept_name gibi birden fazla değere göre sıralama yapmak için Karşılaştırılabilir arayüzü kullanın Tek bir değer için Karşılaştırıcı arayüzünü kullanın


-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);
}

Burada return obj1.compareTo(obj1)veya return obj1.compareTo(obj)ifade sadece Object alır; ilkele izin verilmez. Örneğin

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

Fakat

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

isim String Object olduğundan işe yaradı. Öğrenci sayısını sıralamak istiyorsanız aşağıdaki kodu kullanın.

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

veya

public int compare(Object obj1,Object obj2) { // For Comparator interface
    Student s1 = (Student) obj1;
    Student s2 = (Student) obj2;
    return s1.getRollno() - s2.getRollno();
}  
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.