.Equals () और == ऑपरेटर वाली दो वस्तुओं की तुलना करें


84

मैंने एक Stringक्षेत्र के साथ एक वर्ग का निर्माण किया । फिर मैंने दो ऑब्जेक्ट बनाए और मुझे उन्हें ==ऑपरेटर और .equals()बहुत सारे का उपयोग करके तुलना करनी होगी । यहाँ मैंने क्या किया है:

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


}

संकलन के बाद यह परिणामस्वरूप दो गुना झूठा दिखाता है। यदि दो वस्तुओं का एक ही क्षेत्र - "परीक्षण" है तो यह गलत क्यों है?


7
Btw, को देखते हुए equalsऔर equals2: किसी भी समय आपके पास कुछ ऐसा रूप है जिसे if(a) { return true; } else { return false; }आपको शायद लिखना चाहिए return a
यशवित

@yshavit आपका मतलब है, बूलियन से स्ट्रिंग में बदलाव के साथ?
फास्टकॉवी

4
नहीं, आपका कोड पूछ रहा है कि क्या एक बूलियन एक सच्चा है, और trueयदि यह है और falseअन्यथा। उदाहरण के लिए, if(a.equals(object2)) { return true; } else return falseबस हो सकता है return a.equals(object2)
यशवित

जवाबों:


142

==वस्तु संदर्भ तुलना, यह देखने के लिए कि दो ऑपरेंड एक ही वस्तु (नहीं को इंगित की जाँच करता है बराबर वस्तुओं, एक ही वस्तु)।

यदि आप स्ट्रिंग्स की तुलना करना चाहते हैं (यह देखने के लिए कि क्या उनमें समान वर्ण हैं), तो आपको स्ट्रिंग्स का उपयोग करके तुलना करना होगा equals

आपके मामले में, अगर दो उदाहरणों को MyClassसमान माना जाता है यदि तार मेल खाते हैं, तो:

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

... लेकिन आमतौर पर यदि आप एक वर्ग को परिभाषित कर रहे हैं, तो एक ही क्षेत्र ( aइस मामले में) की समतुल्यता की तुलना में अधिक समानता है ।


साइड नोट: यदि आप ओवरराइड करते हैं equals, तो आपको लगभग हमेशा ओवरराइड करने की आवश्यकता होती है hashCode। जैसा कि इसमें कहा गया हैequals जावाडॉक :

ध्यान दें कि hashCodeजब भी इस विधि को ओवरराइड किया जाता है, तो विधि को ओवरराइड करना आवश्यक होता है, ताकि hashCodeविधि के लिए सामान्य अनुबंध को बनाए रखा जा सके , जो बताता है कि समान वस्तुओं में समान हैश कोड होना चाहिए।


@ टीजे इन == वस्तु संदर्भों की तुलना करता है, विस्तृत करने के लिए, क्या इसका मतलब == दो वस्तुओं के हैशकोड की तुलना करता है?
नरेंद्र जग्गी

@ नरेंद्रजगी - नहीं, इसका मतलब है कि जेवीएम यह देखने के लिए जांच करता है कि दोनों ऑपरेंड दोनों एक ही ऑब्जेक्ट को संदर्भित करते हैं या नहीं। यह जेवीएम तक कैसे है, लेकिन यह सोचने का कोई कारण नहीं है कि यह करने के लिए एक हैशकोड का उपयोग करेगा।
टीजे क्राउडर

19

आपको बराबरी से आगे बढ़ना चाहिए

 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
यह यकीनन सबसे अच्छा जवाब है, हालांकि आप गैर-आदिम प्रकारों के लिए इस (= = null) के बजाय इस (असेंबल्स) का उपयोग करना चाह सकते हैं
goonerify करें

10
मेरा तर्क है कि if (this == null)मामला वैसे भी अनावश्यक है; कॉलिंग nullObject.equals(whatever)एक शून्य पॉइंटर अपवाद को फेंकने वाली है, इसलिए हम सुरक्षित रूप से मान सकते हैं कि thisकिसी भी जावा विधि में शून्य नहीं है जो हम लिख सकते हैं।
मौर्य

1
जब इस असफल हो जायेगी this है lastnameबातिल और पिछले शर्तों को पूरा नहीं करता है।
अहमद राज़

6

ऐसा लग रहा है equals2कि बस फोन कर रहा है equals, इसलिए यह समान परिणाम देगा।


5

ओवरराइट फ़ंक्शन समान () गलत है। ऑब्जेक्ट "a" स्ट्रिंग क्लास का एक उदाहरण है और "ऑब्जेक्ट 2" MyClass क्लास का एक उदाहरण है । वे अलग-अलग वर्ग हैं, इसलिए उत्तर "गलत" है।


5

2 वस्तुओं की तुलना करने का सबसे अच्छा तरीका है कि उन्हें जिंग स्ट्रिंग्स में परिवर्तित करके और स्ट्रिंग्स की तुलना करें, जटिल नीडिंत ऑब्जेक्ट्स, फ़ील्ड्स और / या एरीज़ वाले ऑब्जेक्ट्स से निपटते समय इसका सबसे आसान समाधान।

नमूना:

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
मैं इसे कॉल करना चाहूंगा: ओवरकिल।
रॉल्फ R

@ रॉल्फ R आपकी राय में यह ओवरकिल क्यों है? मैंने इस समस्या के समाधान की तलाश की है और यह अब तक का सबसे आसान समाधान है। किसी भी बेहतर सुझाव का स्वागत है।
m5seppal 13

3
क्योंकि जावा के साथ आप पहले Gsonऑब्जेक्ट बनाने और फिर कॉल करने के बिना वस्तुओं की तुलना कर सकते हैं toJsonGsonऑब्जेक्ट बनाना और तर्क को वास्तव में ऑब्जेक्ट को एक फ्लैट String( toJson) में बदलने के लिए आवश्यक कॉल करना अनावश्यक ओवरहेड है। आप पहले वस्तुओं को जोंस स्ट्रिंग्स में परिवर्तित किए बिना वस्तुओं की तुलना कर सकते हैं (जो कि तेज भी है)।
रॉल्फ R

3

आपका equals2()तरीका हमेशा उतना ही वापस आएगा equals()!!

मेरी टिप्पणियों के साथ आपका कोड :

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
बसreturn a.equals(object2);
मोज़ुबा

2

कथन a == object2और a.equals(object2)दोनों हमेशा वापस आएंगे falseक्योंकि aकुछ stringसमय object2का एक उदाहरण हैMyClass


2

आपके कार्यान्वयन की तरह होना चाहिए:

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

इस कार्यान्वयन के साथ आपके दोनों तरीके काम करेंगे।


2

यदि आपको डिफ़ॉल्ट toString () फ़ंक्शन को कस्टमाइज़ करने की आवश्यकता नहीं है, तो दूसरा तरीका toString () विधि को ओवरराइड करना है, जिसकी तुलना करने के लिए सभी विशेषताओं को लौटाता है। फिर दो वस्तुओं के उत्पादन () आउटपुट की तुलना करें। मैंने IntelliJ IDEA IDE का उपयोग करके स्ट्रींग () विधि उत्पन्न की, जिसमें स्ट्रिंग में वर्ग नाम शामिल है।

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

"==" ऑपरेटर केवल तभी सही होता है जब दो संदर्भ एक ही ऑब्जेक्ट को मेमोरी में इंगित करते हैं। दूसरी ओर बराबर () विधि वस्तु की सामग्री के आधार पर सही होती है।

उदाहरण:

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

आउटपुट: दो स्ट्रिंग्स की तुलना == ऑपरेटर के साथ: झूठी तुलना दो स्ट्रिंग्स की समान सामग्री के साथ समान विधि का उपयोग करके: सही तुलना दो संदर्भों के साथ समान स्ट्रिंग की ओर इशारा करते हुए == ऑपरेटर: सच

आप लिंक से अधिक विवरण भी प्राप्त कर सकते हैं: http://javarevisited.blogspot.in/2012/12/difference-between-equals-method-and-equality-operator-java.html?m=1


2

आपकी कक्षा समान कार्यक्षमता प्राप्त करने के लिए तुलनीय इंटरफ़ेस लागू कर सकती है। आपकी कक्षा को इंटरफ़ेस में घोषित तुलना () विधि को लागू करना चाहिए।

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

वापसी के प्रकार की वस्तु। असमान पहले से ही बूलियन है। शाखाओं के साथ इसे विधि में लपेटने की कोई आवश्यकता नहीं है। इसलिए यदि आप 2 वस्तुओं की तुलना करना चाहते हैं तो बस उनकी तुलना करें:

boolean b = objectA.equals(objectB);

b पहले से ही सही या गलत है।


1

जब हम == का उपयोग करते हैं, तो वस्तु के संदर्भ की तुलना वास्तविक वस्तुओं से नहीं की जाती है। हमें जावा ऑब्जेक्ट्स की तुलना करने के लिए समान विधि को ओवरराइड करने की आवश्यकता है।

कुछ अतिरिक्त जानकारी C ++ में लोडिंग पर ऑपरेटर है और जावा लोडिंग पर ऑपरेटर प्रदान नहीं करता है। जावा में अन्य संभावनाएं भी हैं, इंटरफ़ेस की तुलना करें । यह एक तुलना विधि को परिभाषित करता है।

तुलनित्र इंटरफ़ेस का उपयोग दो वस्तुओं की तुलना करने के लिए भी किया जाता है


4
इस बात पर विचार करें कि आपका उत्तर कुछ नहीं जोड़ता है जो लगभग 2 साल पहले नहीं कहा गया था।
हॉट लिप्स

1

यहां आउटपुट गलत होगा, पहले sopln स्टेटमेंट में गलत बीक्यूज़ आप माईक्लास प्रकार के एक स्ट्रिंग प्रकार की तुलना करने के लिए अन्य MyClass प्रकार की कोशिश कर रहे हैं और यह ऑब्जेक्ट प्रकार दोनों के कारण अनुमति देगा और आपने "==" ऑप्रेटर का उपयोग किया है जो वास्तविक स्मृति नहीं स्मृति के अंदर वास्तविक contnets पकड़े संदर्भ चर मूल्य की जाँच करेगा। दूसरे sopln में भी यह वैसा ही है जैसा कि आप फिर से a.equals (object2) कह रहे हैं, जहाँ a एक ऑब्जेक्ट 1 से भिन्न है। मुझे इस पर अपने निष्कर्षों को बताएं।


2
स्टैकओवरफ्लो बिद्याधर में आपका स्वागत है। प्रश्न दिनांक 14/11/2012 है और पहले से ही एक अच्छी प्रतिक्रिया (ओपी द्वारा अनुमोदित) मिली है। जो आपको मिला वह सही है, लेकिन यह उपयोगी जानकारी नहीं जोड़ रहा है। मेरा सुझाव है कि आप कुछ भी करने से पहले नियमों को पढ़ने के लिए
Nikaido

-3

नीचे दिए गए कोड में आप ओवरराइड विधि को बुला रहे हैं। असमान ()।

सार्वजनिक बूलियन बराबर 2 (ऑब्जेक्ट ऑब्जेक्ट 2) {if (a.equals (ऑब्जेक्ट 2)) {// यहां आप ओवरराइड विधि कह रहे हैं, यही कारण है कि आपको 2 बार गलत मिल रहा है। सच लौटना; } और असत्य वापस; }


1
नहीं, a.equalsयह स्ट्रिंग की विधि है, यह कहीं भी ओवरराइड नहीं है।
तारेक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.