İki nesneyi .equals () ve == operatörüyle karşılaştırın


85

Tek Stringalanlı bir sınıf kurdum . Sonra iki nesne oluşturdum ve bunları ==operatör kullanarak da karşılaştırmalıyım .equals(). İşte yaptığım şey:

public class MyClass {

    String a;

    public MyClass(String ab) {
        a = ab;
    }

    public boolean equals(Object object2) {
        if(a == object2) { 
            return true;
        }
        else return false;
    }

    public boolean equals2(Object object2) {
        if(a.equals(object2)) {
            return true;
        }
        else return false;
    }



    public static void main(String[] args) {

        MyClass object1 = new MyClass("test");
        MyClass object2 = new MyClass("test");

        object1.equals(object2);
        System.out.println(object1.equals(object2));

        object1.equals2(object2);
        System.out.println(object1.equals2(object2));
    }


}

Derlemeden sonra sonuç olarak iki kez yanlış gösterir. İki nesnenin aynı alanlara sahip olması neden yanlıştır - "test"?


7
Btw, bakmak equalsve equals2: formda bir şeye sahip olduğunuz her zaman if(a) { return true; } else { return false; }muhtemelen sadece yazmalısınız return a.
yshavit

@yshavit Boole'den String'e geçişle mi demek istiyorsun?
Fastkowy

4
hayır, kodunuz bir mantıksal değerin doğru olup olmadığını soruyor ve doğru trueolup olmadığını döndürüyor false. Yani örneğin, if(a.equals(object2)) { return true; } else return falsesadece olabilir return a.equals(object2).
yshavit

Yanıtlar:


142

==nesne referanslarını karşılaştırır, iki işlenenin aynı nesneyi işaret edip etmediğini kontrol eder ( eşdeğer nesneler değil , aynı nesneyi).

Dizeleri karşılaştırmak istiyorsanız (aynı karakterleri içerip içermediklerini görmek için), dizeleri kullanarak karşılaştırmanız gerekir. equals .

Sizin durumunuzda, MyClassdizeler eşleşiyorsa, gerçekten iki örnek eşit kabul edilirse, o zaman:

public boolean equals(Object object2) {
    return object2 instanceof MyClass && a.equals(((MyClass)object2).a);
}

... ama genellikle bir sınıf tanımlıyorsanız, tek bir alanın eşdeğerliğinden daha fazlası vardır ( abu durumda).


Yan not: Geçersiz kılarsanız equals, neredeyse her zaman geçersiz kılmanız gerekir hashCode. O dediği gibi equalsJavaDoc'u :

Eşit nesnelerin eşit karma kodlara sahip olması gerektiğini belirten yönteme hashCodeilişkin genel sözleşmeyi sürdürmek için, bu yöntem geçersiz kılındığında genellikle yöntemi geçersiz kılmanın gerekli hashCodeolduğuna dikkat edin.


@TJ In == detaylandırmak için nesne referanslarını karşılaştırır, == iki nesnenin karma kodunu karşılaştırdığı anlamına mı gelir?
Narendra Jaggi

@NarendraJaggi - Hayır, bu JVM'nin her ikisinin de aynı nesneyi ifade edip etmediğini kontrol ettiği anlamına gelir. Bunu nasıl yaptığı JVM'ye bağlıdır, ancak bunu yapmak için bir karma kod kullanacağını düşünmek için hiçbir neden yoktur.
TJ Crowder

19

Eşitleri geçersiz kılmalısınız

 public boolean equals (Object obj) {
     if (this==obj) return true;
     if (this == null) return false;
     if (this.getClass() != obj.getClass()) return false;
     // Class name is Employ & have lastname
     Employe emp = (Employee) obj ;
     return this.lastname.equals(emp.getlastname());
 }

2
Bu muhtemelen en iyi cevaptır, ancak ilkel olmayan türler için (this == null) yerine this.equals (obj) kullanmak isteyebilirsiniz
goonerify

10
if (this == null)Zaten davanın gereksiz olduğunu iddia ediyorum ; çağırmak nullObject.equals(whatever)bir boş işaretçi istisnası atacak, bu yüzden yazabileceğimiz thisherhangi bir Java yönteminde bunun boş olmadığını güvenle varsayabiliriz .
Maura

5

Görünüşe equals2göre sadece arıyor equals, bu yüzden aynı sonuçları verecek.


1
OP, sınıfın bir üyesi olan equalsString'in yöntemini çağırıyor a. equals2çağırmıyorequals
Yiğit Alparslan

1
Evet teşekkürler. Görünüşe göre MyClass ve String arasındaki karışıklığı tamamen kaçırdım ki bu gerçek sorun.
Hew Wolff

5

Üzerine yazma işlevi eşittir () yanlış. "A" nesnesi, String sınıfının bir örneğidir ve "nesne2", MyClass sınıfının bir örneğidir . Bunlar farklı sınıflardır, dolayısıyla cevap "yanlış" tır.


5

2 nesneyi karşılaştırmanın en iyi yolu, onları json dizelerine dönüştürmek ve dizeleri karşılaştırmaktır; bu, diziler içeren karmaşık iç içe nesneler, alanlar ve / veya nesnelerle uğraşırken en kolay çözümdür.

örneklem:

import com.google.gson.Gson;


Object a = // ...;
Object b = //...;
String objectString1 = new Gson().toJson(a);
String objectString2 = new Gson().toJson(b); 

if(objectString1.equals(objectString2)){
    //do this
}

9
Ben buna aşırı öldürme demek istiyorum.
Rolf ツ

@Rolf ツ Sizce bu neden fazla abartılı? Bu soruna bir çözüm aradım ve şu ana kadar bulduğum en kolay çözüm bu. Daha iyi bir öneriye açığız.
m5seppal

3
Çünkü Java ile nesneleri önce bir Gsonnesne oluşturup sonra çağırmadan karşılaştırabilirsiniz toJson. GsonNesneyi oluşturmak ve gerçekte nesneyi düz String( toJson) düzeye dönüştürmek için gereken mantığı çağırmak gereksiz ek yüktür. Nesneleri, önce nesneleri Json dizelerine dönüştürmeden karşılaştırabilirsiniz (bu da daha hızlıdır).
Rolf ツ

3

Kişisel equals2()yöntem hep aynı dönecektir equals()!!

Yorumlarımla birlikte kodunuz :

public boolean equals2(Object object2) {  // equals2 method
    if(a.equals(object2)) { // if equals() method returns true
        return true; // return true
    }
    else return false; // if equals() method returns false, also return false
}

5
Justreturn a.equals(object2);
mojuba

2

İfadeler a == object2ve a.equals(object2)her ikisi de her zaman geri dönecektir falseçünkü ais a stringwhile object2,MyClass


2

Uygulamanızın beğenmesi gerekenler:

public boolean equals2(Object object2) {
    if(a.equals(object2.a)) {
        return true;
    }
    else return false;
}

Bu uygulama ile her iki yönteminiz de işe yarayacaktır.


2

Varsayılan toString () işlevini özelleştirmeniz gerekmiyorsa, başka bir yol da karşılaştırılacak tüm öznitelikleri döndüren toString () yöntemini geçersiz kılmaktır. sonra iki nesnenin çıktısınıString () ile karşılaştırın. Dizede sınıf adını içeren IntelliJ IDEA IDE'yi kullanarak toString () yöntemini oluşturdum.

public class Greeting {
private String greeting;

@Override
public boolean equals(Object obj) {
    if (this == obj) return true;
    return this.toString().equals(obj.toString());
}

@Override
public String toString() {
    return "Greeting{" +
            "greeting='" + greeting + '\'' +
            '}';
}
}

2

"==" operatörü, yalnızca iki referans bellekteki aynı nesneyi işaret ediyorsa true döndürür. Öte yandan equals () yöntemi, nesnenin içeriğine bağlı olarak true değerini döndürür.

Misal:

String personalLoan = new String("cheap personal loans");
String homeLoan = new String("cheap personal loans");

//since two strings are different object result should be false
boolean result = personalLoan == homeLoan;
System.out.println("Comparing two strings with == operator: " + result);

//since strings contains same content , equals() should return true
result = personalLoan.equals(homeLoan);
System.out.println("Comparing two Strings with same content using equals method: " + result);

homeLoan = personalLoan;
//since both homeLoan and personalLoan reference variable are pointing to same object
//"==" should return true
result = (personalLoan == homeLoan);
System.out.println("Comparing two reference pointing to same String with == operator: " + result);

Çıktı: == operatörüyle iki dizeyi karşılaştırma: false Eşittir yöntemini kullanarak aynı içeriğe sahip iki Dizeyi karşılaştırma: true Aynı String'i gösteren iki referansın == operatörüyle karşılaştırılması: true

Bağlantıdan daha fazla ayrıntı da edinebilirsiniz: http://javarevisited.blogspot.in/2012/12/difference-between-equals-method-and-equality-operator-java.html?m=1


2

Sınıfınız, aynı işlevselliği elde etmek için Karşılaştırılabilir arabirimi uygulayabilir. Sınıfınız, arabirimde bildirilen CompareTo () yöntemini uygulamalıdır.

public class MyClass implements Comparable<MyClass>{

    String a;

    public MyClass(String ab){
        a = ab;
    }

    // returns an int not a boolean
    public int compareTo(MyClass someMyClass){ 

        /* The String class implements a compareTo method, returning a 0 
           if the two strings are identical, instead of a boolean.
           Since 'a' is a string, it has the compareTo method which we call
           in MyClass's compareTo method.
        */

        return this.a.compareTo(someMyClass.a);

    }

    public static void main(String[] args){

        MyClass object1 = new MyClass("test");
        MyClass object2 = new MyClass("test");

        if(object1.compareTo(object2) == 0){
            System.out.println("true");
        }
        else{
            System.out.println("false");
        }
    }
}

1

object.equals'ın dönüş türü zaten boole'dir. dalları olan bir yönteme sarmaya gerek yoktur. yani 2 nesneyi karşılaştırmak istiyorsanız, bunları basitçe karşılaştırın:

boolean b = objectA.equals(objectB);

b zaten doğru ya da yanlış.


1

== kullandığımızda, nesnenin Referansı gerçek nesnelerle karşılaştırılmaz. Java Nesnelerini karşılaştırmak için eşittir yöntemini geçersiz kılmamız gerekir.

Bazı ek bilgiler C ++ 'da operatör aşırı yükleme vardır ve Java operatöre aşırı yükleme sağlamaz. Java'daki diğer olasılıklar da , bir ComparTo yöntemini tanımlayan Karşılaştırma Arayüzü'nü uygulamaktır .

Karşılaştırıcı arayüzü ayrıca iki nesneyi karşılaştırmak için kullanılır


4
Cevabınızın neredeyse 2 yıl önce söylenmeyen hiçbir şeyi eklemediğini düşünün.
Hot Licks

1

Burada çıktı false olacaktır, çünkü ilk sopln deyiminde Myclass türünden bir değişken dizge türünü diğer MyClass türüyle karşılaştırmaya çalışıyorsunuz ve her ikisinin de Object türü olması ve "==" operatörünü kullandınız. gerçek hafızayı tutan referans değişken değerini hafızanın içindeki gerçek kontrolleri değil kontrol edecektir. İkinci sopln'de de, a.equals (nesne2) 'yi çağırmanızla aynıdır, burada a, object1 içinde bir değişkendir. Bu konudaki bulgularınızı bana bildirin.


2
Stackoverflow bidyadhar'a hoş geldiniz. Soru 14/11/2012 tarihli ve halihazırda iyi bir yanıt aldı (OP tarafından onaylandı). Sahip olduğunuz doğru, ancak yararlı bilgiler eklemiyor. Herhangi bir şey yapmadan önce kuralları okumanızı öneririm
Nikaido

-3

Aşağıdaki kodda geçersiz kılma yöntemini .equals () çağırıyorsunuz.

public boolean equals2 (Object object2) {if (a.equals (object2)) {// burada overriden yöntemini çağırıyorsunuz, bu yüzden 2 kez false alıyorsunuz. doğruya dön; } aksi takdirde yanlış döndürür; }


1
Hayır, a.equalsdizenin metodudur, hiçbir yerde geçersiz kılınmaz.
Tarec
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.