2010-10-27 14 views
13

जैसा कि यह कहा गया है कि == ऑपरेटर ऑब्जेक्ट संदर्भों की तुलना करने के लिए तुलना करता है कि वे एक ही वस्तु पर एक ही वस्तु का जिक्र कर रहे हैं या नहीं। यदि ऐसा है तो मुझे कोड के इस टुकड़े के लिए "समान" क्यों मिल रहा है?यदि == जावा में संदर्भों की तुलना करता है, तो इन स्ट्रिंग्स के साथ यह सच क्यों मूल्यांकन करता है?

public class Salmon { 
    public static void main(String[] args) { 

     String str1 = "Str1"; 
     String str2 = "Str1"; 

     if (str1 == str2) { 
      System.out.println("Equal"); 
     } else { 
      System.out.println("Not equal"); 
     } 
    } 
} 
+1

क्या आप वाकई '==' या '=' ?? का उपयोग कर चुके हैं ?? –

+0

एक कोड उदाहरण बदल दिया, क्षमा करें – Eugene

+1

यह कहना सुनिश्चित करें कि भाषा जावा है। अन्य भाषाओं में अन्य कार्यान्वयन होगा। जो भी == ऑपरेटर को .NET के लिए करने के लिए ओवरलोड किया गया है। – CodingBarfield

उत्तर

37

कार्यक्रम Equal प्रिंट करेगा। (कम से कम सूर्य हॉटस्पॉट का उपयोग करने और javac सूर्य।) यहाँ उस पर http://ideone.com/8UrRrk

इस तथ्य यह है कि स्ट्रिंग-शाब्दिक स्थिरांक एक स्ट्रिंग पूल में जमा हो जाती है और स्ट्रिंग का संदर्भ की वजह से है पुन: उपयोग किया जा सकता है प्रदर्शन किया है ।

अतिरिक्त पठन:


हालांकि यह:

public class Salmon { 
    public static void main(String[] args) { 

     String str1 = "Str1"; 
     String str2 = new String("Str1"); 

     if (str1 == str2) { 
      System.out.println("Equal"); 
     } else { 
      System.out.println("Not equal"); 
     } 
    } 
} 

प्रिंट होगा new के बाद सेएक ताजा संदर्भ पेश करने की गारंटी है।

तो, अंगूठे का नियम: हमेशा equals विधि का उपयोग करके तारों की तुलना करें।

+0

+1 को शामिल करके गतिशील रूप से निर्मित स्ट्रिंग्स को प्रशिक्षित कर सकते हैं। मैं इस तरह एक वेबपैप एक लंबे समय के लिए चाहता था। यहां तक ​​कि इसे खुद लिखने का विचार भी है लेकिन वहां है। –

+3

पूर्णता के लिए 'नई स्ट्रिंग ("स्ट्र 1")। इंटर्न() '" समान "प्रिंट भी करेगा :) – OscarRyz

+0

@ ऑस्करराइज़, अच्छा बिंदु। धन्यवाद! :-) – aioobe

3

इस कोड Equal मुद्रित नहीं होंगे।
लेकिन यदि दोनों तार समान थे, तो यह मामला विशेष होगा।

अब जब आपने अपना कोड अपडेट कर लिया

, यह मामला है:

एक साधारण (लेकिन पूरी तरह से नहीं सटीक) व्याख्या यह है कि संकलक देखते हैं कि दो तार ही कर रहे हैं और इस तरह कुछ करना है:

String str1 = "Str1"; 
String str2 = str1; 

क्या वास्तव में यहाँ होता है कि संकलक शाब्दिक स्ट्रिंग देख सकते हैं और "शाब्दिक पूल स्ट्रिंग" में रख जाएगा।

एक स्ट्रिंग को संशोधित नहीं किया जा सकता है (यह अपरिवर्तनीय है) स्ट्रिंग्स (संकलन के दौरान पाए गए) के शाब्दिक मूल्यों को "पूल" में रखा जाता है।
इस तरह, यदि दो अलग-अलग शाब्दिक तार होते हैं जिनमें एक ही सामग्री होती है (जैसे इस विशेष मामले में), स्मृति "स्ट्र 1" और "स्ट्र 1" को दो बार स्टोर करने के लिए बर्बाद नहीं होती है।

+0

मैं हूं क्षमा करें, मैंने कोड उदाहरण में सुधार जोड़ा है। – Eugene

3

जावा सभी स्ट्रिंग्स को एक रन के दौरान आंतरिक रूप से स्ट्रिंग टेबल में स्टोर करता है। दो तारों के संदर्भ समान हैं क्योंकि स्मृति में वे एक ही स्थान पर संग्रहीत होते हैं। इसलिए, Equal

आपका कथन सही है, == ऑब्जेक्ट संदर्भों की तुलना करता है। किसी भी अन्य वर्ग के साथ एक ही चीज की कोशिश करें लेकिन स्ट्रिंग्स और आपको एक ही परिणाम नहीं मिलेगा।

+0

यह करता है? क्या आप मुझे इस दावे को वापस करने का संदर्भ दे सकते हैं? –

+1

एओओब एक बेहतर स्पष्टीकरण देता है, क्योंकि इस व्यवहार की गारंटी नहीं है। और यह केवल एक स्ट्रिंग अक्षर पर लागू होता है, न कि किसी प्रोग्राम में प्रत्येक स्ट्रिंग के लिए। – Joey

+2

जावा एपीआई दस्तावेज़ों से: "सभी शाब्दिक तार और स्ट्रिंग-मूल्यवान निरंतर अभिव्यक्तियों को प्रशिक्षित किया जाता है।" Http://download.oracle.com/javase/1.4.2/docs/api/java/lang/String.html#intern%28%29 देखें ध्यान दें कि केवल स्थिर तार स्वचालित रूप से इंटर्न किए जाएंगे। Ideone.com से जुड़ने के लिए आप String.intern() –

0

उपरोक्त टिप्पणियों ने इसे बहुत अच्छी तरह से समझाया है।

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

String str1 = "Str1"; 
String str2 = "Str"; str2 += "1"; 

अब प्रिंट बराबर

2

लोग, आप भूल कर रहे हैं ऐसा नहीं है कि पूल में शाब्दिक तार रखने की प्रक्रिया "होना शामिल" कहा जाता है चाहिए। कक्षा स्ट्रिंग में एक तरीका है जिसे इंटर्न() कहा जाता है। यह विधि पूल में किसी भी स्ट्रिंग को रखती है, भले ही यह पूल में प्रारंभिक नहीं है (शाब्दिक नहीं)। इसका मतलब यह है कि इस तरह कोड:

String a = "hello"; 
String b = new String("hello"); 
b = b.intern(); 

System.out.println(a == b); 

प्रिंट होगा "true"। अब, किसी को इसकी आवश्यकता क्यों होगी? जैसा कि आप कल्पना कर सकते हैं, स्ट्रिंग तुलना a.equals(b) स्ट्रिंग एक ही लम्बाई है लेकिन अंत के करीब अलग होने में काफी समय लग सकता है। (बस .equals() स्रोत कोड देखें।)।

हालांकि, संदर्भों की तुलना सीधे पूर्णांक (सी बोलने में पॉइंटर्स) की तुलना में समान है, जो तत्काल निकट है।

तो, यह आपको क्या देता है? स्पीड। यदि आपको कई स्ट्रिंग्स की तुलना कई बार करना है, तो कई बार, प्रोग्राम प्रदर्शन का लाभ बहुत अधिक होगा यदि आप इन स्ट्रिंग्स को प्रशिक्षित करते हैं। यदि आप केवल एक बार तारों की तुलना करने जा रहे हैं, तो कोई प्रदर्शन लाभ नहीं होगा क्योंकि आंतरिक प्रक्रिया स्वयं बराबर() का उपयोग करती है।

मुझे आशा है कि यह यह समझाएगा।

धन्यवाद

संबंधित मुद्दे