Scala में ==और किसके बीच क्या अंतर है .equals()और कब उपयोग करना है?
क्या कार्यान्वयन जावा में समान है?
EDIT: संबंधित प्रश्न विशिष्ट मामलों के बारे में बात करता है AnyVal। अधिक सामान्य मामला है Any।
Scala में ==और किसके बीच क्या अंतर है .equals()और कब उपयोग करना है?
क्या कार्यान्वयन जावा में समान है?
EDIT: संबंधित प्रश्न विशिष्ट मामलों के बारे में बात करता है AnyVal। अधिक सामान्य मामला है Any।
जवाबों:
आप सामान्य रूप से इसका उपयोग ==करते हैं equals, सिवाय इसके कि यह nullठीक से व्यवहार करता है। संदर्भ समानता (शायद ही कभी इस्तेमाल किया जाता है) eq।
3 == BigInt(3)और BigInt(3) == 3सही हैं। लेकिन, 3.equals(BigInt(3))झूठ है, जबकि BigInt(3).equals(3)सच है। इसलिए, का उपयोग करना पसंद करते हैं ==। equals()स्कैला में उपयोग करने से बचें । मुझे लगता ==है कि निहितार्थ अच्छी तरह से equals()करता है , लेकिन नहीं करता है।
new java.lang.Integer(1) == new java.lang.Double(1.0)हुए new java.lang.Integer(1) equals new java.lang.Double(1.0)भी सत्य क्यों है ?
equalsप्रत्येक उदाहरण की सामग्री की तुलना करने के लिए ओवरराइड विधि। यह equalsजावा में उपयोग की जाने वाली एक ही विधि है==चिंता किए बिना, तुलना करने के लिए ऑपरेटर का उपयोग करेंnulleqयह जांचने के लिए विधि का उपयोग करें कि क्या दोनों तर्क बिल्कुल एक ही संदर्भ हैं। अनुशंसित है कि जब तक आप यह नहीं समझेंगे कि यह कैसे काम करता है और अक्सर 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 संकलन नहीं करेगा, क्योंकि इसके लिए दोनों प्रकार के तर्क की आवश्यकता होती है AnyRefnew ArrayList() equals new ArrayList()वापस आ जाएगा true, क्योंकि यह सामग्री की जाँच करता हैnew ArrayList() == new ArrayList()वापस आ जाएगा true, क्योंकि यह करने के लिए पुनर्निर्देशित करता हैequals(...)new ArrayList() eq new ArrayList()वापस आ जाएगी false, के रूप में दोनों बहस विभिन्न उदाहरण हैंfoo equals fooवापस आ जाएगी true, जब तक fooहै null, तो एक फेंक होगाNullPointerExceptionfoo == fooवापस आ जाएगी true, भले ही fooहैnullfoo eq footrueदोनों तर्कों के एक ही संदर्भ से जुड़ने के बाद वापस लौट आएंगेवहाँ के बीच एक दिलचस्प अंतर नहीं है ==और 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: