स्काला में == और। असमान के बीच क्या अंतर है?


144

Scala में ==और किसके बीच क्या अंतर है .equals()और कब उपयोग करना है?

क्या कार्यान्वयन जावा में समान है?

EDIT: संबंधित प्रश्न विशिष्ट मामलों के बारे में बात करता है AnyVal। अधिक सामान्य मामला है Any



@ क्या मुझे लगता है कि पूछे गए तारीख को देखते हुए अन्य प्रश्न को डुप्लिकेट के रूप में चिह्नित किया जाना चाहिए। साथ ही, मुझे लगता है कि दोनों प्रश्न अलग-अलग हैं।
जुस 12

जवाबों:


201

आप सामान्य रूप से इसका उपयोग ==करते हैं equals, सिवाय इसके कि यह nullठीक से व्यवहार करता है। संदर्भ समानता (शायद ही कभी इस्तेमाल किया जाता है) eq


12
क्या यह जावा पुस्तकालयों का उपयोग करते समय भी लागू होता है?
Jus12

20
ऐसा होता है। उदाहरण के लिए नए java.util.ArrayList [Int] (= = new java.util.ArrayList [Int]), ArrayList पर बराबर सामग्री समानता है।
डिडियर ड्यूपॉन्ट

5
इंट और लॉन्ग और == बनाम। असमान () के आसपास कुछ अजीब व्यवहार भी है। Int और as Long के लिए समान संख्या == के लिए सही है, लेकिन समान के लिए गलत है। तो == हमेशा बराबरी के लिए मार्ग नहीं करता है।
हेरोल्ड एल

24
ज्यादा दिलचस्प, दोनों 3 == BigInt(3)और BigInt(3) == 3सही हैं। लेकिन, 3.equals(BigInt(3))झूठ है, जबकि BigInt(3).equals(3)सच है। इसलिए, का उपयोग करना पसंद करते हैं ==equals()स्कैला में उपयोग करने से बचें । मुझे लगता ==है कि निहितार्थ अच्छी तरह से equals()करता है , लेकिन नहीं करता है।
Naetmul

तो असत्य होते new java.lang.Integer(1) == new java.lang.Double(1.0)हुए new java.lang.Integer(1) equals new java.lang.Double(1.0)भी सत्य क्यों है ?
इस्टसुन

34

==एक अंतिम विधि है, और कॉल .equals, जो अंतिम नहीं है।

यह जावा की तुलना में मौलिक रूप से भिन्न है, जहां ==एक विधि के बजाय एक ऑपरेटर है और वस्तुओं के लिए संदर्भ समानता की कड़ाई से तुलना करता है।


29

टी एल; डॉ

  • equalsप्रत्येक उदाहरण की सामग्री की तुलना करने के लिए ओवरराइड विधि। यह equalsजावा में उपयोग की जाने वाली एक ही विधि है
  • संदर्भों की ==चिंता किए बिना, तुलना करने के लिए ऑपरेटर का उपयोग करेंnull
  • eqयह जांचने के लिए विधि का उपयोग करें कि क्या दोनों तर्क बिल्कुल एक ही संदर्भ हैं। अनुशंसित है कि जब तक आप यह नहीं समझेंगे कि यह कैसे काम करता है और अक्सर equalsइसके बजाय आपको जो काम करना है उसके लिए काम करेगा। और केवल AnyRefतर्कों के साथ इसका उपयोग करना सुनिश्चित करें , न कि केवलAny

नोट: के मामले पर equals, बस जावा में के रूप में, यह एक ही परिणाम वापस नहीं कर सकते अगर आप तर्क जैसे स्विच 1.equals(BigInt(1))वापस आ जाएगी falseजहां उलटा वापस आ जाएगी true। इसका कारण यह है कि प्रत्येक कार्यान्वयन केवल विशिष्ट प्रकारों की जाँच करता है। आदिम संख्या की जाँच न करें कि क्या दूसरा तर्क Numberन तो BigIntप्रकार का है बल्कि केवल अन्य आदिम प्रकारों का है

विवरण

AnyRef.equals(Any)विधि उपवर्गों द्वारा ओवरराइड से एक है। जावा स्पेसिफिकेशन की एक विधि जो स्काला के ऊपर भी आ गई है। यदि एक अनबॉक्सिंग इंस्टेंस पर उपयोग किया जाता है, तो इसे कॉल करने के लिए बॉक्सिंग किया जाता है (हालांकि स्कैला में छिपा हुआ है; जावा के साथ अधिक स्पष्ट int-> Integer)। डिफ़ॉल्ट कार्यान्वयन केवल संदर्भों की तुलना करता है (जैसा कि जावा में है)

Any.==(Any)विधि दो वस्तुओं तुलना करता है और (जैसे कि दो उदाहरणों के साथ एक स्थिर विधि बुला) या तो तर्क अशक्त होने के लिए अनुमति देता है। यह तुलना करता है यदि दोनों हैं null, तो यह equals(Any)बॉक्सिंग उदाहरण पर विधि को कॉल करता है ।

AnyRef.eq(AnyRef)विधि तुलना केवल संदर्भ, यह है कि जहां उदाहरण स्मृति में स्थित है। इस विधि के लिए कोई निहित बॉक्सिंग नहीं है।

उदाहरण

  • 1 equals 2वापस आ जाएगा false, क्योंकि यह करने के लिए पुनर्निर्देशित करता हैInteger.equals(...)
  • 1 == 2वापस आ जाएगा false, क्योंकि यह करने के लिए पुनर्निर्देशित करता हैInteger.equals(...)
  • 1 eq 2 संकलन नहीं करेगा, क्योंकि इसके लिए दोनों प्रकार के तर्क की आवश्यकता होती है AnyRef
  • new ArrayList() equals new ArrayList()वापस आ जाएगा true, क्योंकि यह सामग्री की जाँच करता है
  • new ArrayList() == new ArrayList()वापस आ जाएगा true, क्योंकि यह करने के लिए पुनर्निर्देशित करता हैequals(...)
  • new ArrayList() eq new ArrayList()वापस आ जाएगी false, के रूप में दोनों बहस विभिन्न उदाहरण हैं
  • foo equals fooवापस आ जाएगी true, जब तक fooहै null, तो एक फेंक होगाNullPointerException
  • foo == fooवापस आ जाएगी true, भले ही fooहैnull
  • foo eq footrueदोनों तर्कों के एक ही संदर्भ से जुड़ने के बाद वापस लौट आएंगे

6

वहाँ के बीच एक दिलचस्प अंतर नहीं है ==और equalsके लिए Floatऔर Doubleप्रकार: वे इलाज NaNअलग ढंग से:

scala> Double.NaN == Double.NaN
res3: Boolean = false

scala> Double.NaN equals Double.NaN
res4: Boolean = true

संपादित करें: जैसा कि एक टिप्पणी में बताया गया था - "यह जावा में भी होता है" - इस पर निर्भर करता है कि वास्तव में यह क्या है:

public static void main(final String... args) {
    final double unboxedNaN = Double.NaN;
    final Double boxedNaN = Double.valueOf(Double.NaN);

    System.out.println(unboxedNaN == unboxedNaN);
    System.out.println(boxedNaN == boxedNaN);
    System.out.println(boxedNaN.equals(boxedNaN));
}

यह छपेगा

false
true
true

तो, unboxedNanपैदावार falseजब समानता के लिए तुलना की जाती है क्योंकि यह है कि IEEE फ़्लोटिंग पॉइंट नंबर इसे कैसे परिभाषित करते हैं और यह वास्तव में हर प्रोग्रामिंग भाषा में होना चाहिए (हालांकि यह किसी तरह पहचान की धारणा के साथ खिलवाड़ करता है)।

==जावा में उपयोग की तुलना के लिए बॉक्सिंग NaN पैदावार सही है क्योंकि हम ऑब्जेक्ट रेफरेंस की तुलना कर रहे हैं।

मेरे पास equalsकेस के लिए स्पष्टीकरण नहीं है , IMHO इसे वास्तव में ==अनबॉक्स किए गए दोहरे मानों के समान व्यवहार करना चाहिए , लेकिन यह नहीं करता है।

स्काला के लिए अनुवादित मामला थोड़ा अधिक जटिल है क्योंकि स्काला ने आदिम और वस्तु प्रकारों को एकीकृत किया है Anyऔर आवश्यकतानुसार आदिम डबल और बॉक्सिंग डबल में अनुवाद किया है। इस प्रकार यह स्कोला ==जाहिरा तौर पर आदिम NaNमूल्यों की तुलना में उबलता है, लेकिन equalsबॉक्सिंग डबल वैल्यू पर परिभाषित एक का उपयोग करता है (इसमें बहुत अधिक निहित रूपांतरण जादू चल रहा है और इसमें डबल्स पर ढेर लगाया गया है RichDouble)।

यदि आपको वास्तव में यह पता लगाने की आवश्यकता है कि क्या वास्तव में कुछ NaNउपयोग किया जाता है isNaN:


और यह जावा में भी होता है!
इवान सतरिया

4

Scala == में पहले Null मानों की जाँच करें और फिर पहले ऑब्जेक्ट पर बराबर पद्धति को कॉल करें

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