मैं जावा में तार की तुलना कैसे करूं?


724

मैं ==अब तक अपने सभी तार की तुलना करने के लिए अपने प्रोग्राम में ऑपरेटर का उपयोग कर रहा हूं । हालाँकि, मैं एक बग में भाग गया, उनमें से एक को .equals()बदले, और इसने बग को ठीक कर दिया।

है ==बुरा? यह कब होना चाहिए और इसका उपयोग नहीं किया जाना चाहिए? क्या फर्क पड़ता है?


12
यह जानने के लिए भी अच्छा है कि, यदि आप। अधिक जानकारी के लिए जावा डॉक देखें।
नागेश्वरन

==वस्तुओं पर काम करने के तरीके पर मेरे स्पष्टीकरण के लिए एक लिंक छोड़कर : stackoverflow.com/a/19966154/2284641
जोहान्स एच।

==कुछ समय तक काम करेगा, क्योंकि जावा में एक स्ट्रिंग पूल है, जहां यह आमतौर पर उपयोग किए जाने वाले तारों के मेमोरी संदर्भों का पुन: उपयोग करने की कोशिश करता है। लेकिन ==तुलना करता है कि वस्तुएं समान हैं, मूल्य नहीं ... इसलिए .equals()उचित उपयोग है जिसे आप उपयोग करना चाहते हैं।
जेम्स ओर्वेक

परीक्षण करने के लिए कभी भी == का उपयोग न करें कि स्ट्रिंग्स समान हैं, जब तक कि आप सूक्ष्म त्रुटियों को ट्रैक करने और जावा स्ट्रिंग इंटर्निंग प्रक्रिया की जटिलताओं का अध्ययन करने का आनंद नहीं लेते हैं। "12"=="1"+2गलत है (शायद)
फ्लाइट ओडिसी

जवाबों:


5558

== संदर्भ समानता के लिए परीक्षण (चाहे वे एक ही वस्तु हों)।

.equals() मूल्य समानता के लिए परीक्षण (चाहे वे तार्किक रूप से "समान" हों)।

nullकॉल .equals()करने से पहले Objects.equals () की जाँच करता है ताकि आपको (JDK7 के रूप में उपलब्ध नहीं हो, अमरूद में भी उपलब्ध )।

नतीजतन, यदि आप परीक्षण करना चाहते हैं कि क्या दो तारों का एक ही मूल्य है जो आप शायद उपयोग करना चाहते हैं Objects.equals()

// These two have the same value
new String("test").equals("test") // --> true 

// ... but they are not the same object
new String("test") == "test" // --> false 

// ... neither are these
new String("test") == new String("test") // --> false 

// ... but these are because literals are interned by 
// the compiler and thus refer to the same object
"test" == "test" // --> true 

// ... string literals are concatenated by the compiler
// and the results are interned.
"test" == "te" + "st" // --> true

// ... but you should really just call Objects.equals()
Objects.equals("test", new String("test")) // --> true
Objects.equals(null, "test") // --> false
Objects.equals(null, null) // --> true

आप लगभग हमेशा उपयोग करना चाहते हैं Objects.equals()। में दुर्लभ स्थिति है जहाँ आप जानते हैं कि आप के साथ हैं निपटने प्रशिक्षु तार, आप कर सकते हैं का उपयोग करें ==

से JLS 3.10.5। स्ट्रिंग साहित्य :

इसके अलावा, एक स्ट्रिंग शाब्दिक हमेशा कक्षा के एक ही उदाहरण को संदर्भित करता है String। इसका कारण यह है कि स्ट्रिंग शाब्दिक - या, अधिक सामान्यतः, स्ट्रिंग्स जो निरंतर अभिव्यक्तियों ( .215.28 ) के मान हैं - "इंटर्न" हैं ताकि विधि का उपयोग करके, अद्वितीय उदाहरण साझा करें String.intern

इसी तरह के उदाहरण जेएलएस 3.10.5-1 में भी देखे जा सकते हैं ।

विचार करने के अन्य तरीके

String.equalsIgnoreCase () मान समानता जो मामले को अनदेखा करता है।

String.contentEquals ()String किसी की सामग्री के साथ तुलना करता है CharSequence(जावा 1.5 के बाद से उपलब्ध है)। समानता की तुलना करने से पहले आपको अपने स्ट्रिंगरबफ़र इत्यादि को एक स्ट्रिंग में बदलने से बचाता है, लेकिन आपको चेक करना बंद कर देता है।


3
यदि == संदर्भ समानता के लिए जाँच क्यों n == 5 समझ में आता है? 5 एक चर नहीं है
हित रॉय

2
@HritRoy क्योंकि एक चर ==के मूल्य की जाँच करता है । जब आपके पास कोई ऑब्जेक्ट होता है, तो जो चर ऑब्जेक्ट को संदर्भित करता है, उसके पास ऑब्जेक्ट का संदर्भ मूल्य होता है । इस प्रकार, आप दो चर की तुलना करते समय संदर्भों की तुलना करते हैं ==। जब एक आदिम डेटा प्रकार की तुलना करते हैं int, तो यह अभी भी एक ही मामला है। प्रकार के एक चर में intपूर्णांक मान के रूप में होता है। इस प्रकार, आप intउपयोग करने वाले दो एस के मूल्यों की तुलना करते हैं ==। यदि intवैरिएबल का मान है या मैजिक नंबर मायने नहीं रखता है। इसके अतिरिक्त: एक संदर्भ और कुछ नहीं बल्कि एक संख्या है जो मेमोरी को संदर्भित करता है।
akuzminykh

718

==ऑब्जेक्ट संदर्भों का .equals()परीक्षण करता है, स्ट्रिंग मानों का परीक्षण करता है।

कभी-कभी ऐसा लगता है जैसे ==मानों की तुलना करता है, क्योंकि जावा कुछ पीछे-पीछे चलने वाले सामान को सुनिश्चित करने के लिए करता है कि समान-लाइन स्ट्रिंग्स वास्तव में एक ही वस्तु हैं।

उदाहरण के लिए:

String fooString1 = new String("foo");
String fooString2 = new String("foo");

// Evaluates to false
fooString1 == fooString2;

// Evaluates to true
fooString1.equals(fooString2);

// Evaluates to true, because Java uses the same object
"bar" == "bar";

लेकिन नल से सावधान रहें!

==nullस्ट्रिंग को ठीक से संभालता है, लेकिन .equals()अशक्त स्ट्रिंग से कॉल करने पर अपवाद होगा:

String nullString1 = null;
String nullString2 = null;

// Evaluates to true
System.out.print(nullString1 == nullString2);

// Throws a NullPointerException
System.out.print(nullString1.equals(nullString2));

इसलिए यदि आप जानते हैं कि fooString1अशक्त हो सकता है, तो पाठक को बताएं कि लिखकर

System.out.print(fooString1 != null && fooString1.equals("bar"));

निम्नलिखित कम हैं, लेकिन यह कम स्पष्ट है कि यह अशक्त के लिए जाँच करता है:

System.out.print("bar".equals(fooString1));  // "bar" is never null
System.out.print(Objects.equals(fooString1, "bar"));  // Java 7 required

86
कभी कभी यह के रूप में यदि "==" मूल्यों तुलना लग रहा है, - == ऐसा हमेशा तुलना मूल्यों! (यह सिर्फ इतना है कि कुछ निश्चित संदर्भ हैं!)
एआईओबी जूल

6
काश, isNullOrEmpty (), और ऑपरेटरों के कोई कस्टम ओवरलोडिंग के लिए कोई स्थिर तरीका नहीं है, जो जावा # के इस भाग को C # या पायथन की तुलना में बनाता है। और चूंकि जावा में विस्तार विधियाँ नहीं हैं, आप java.lang.String को विस्तारित करने के लिए अपनी उपयोगिता नहीं लिख सकते। सही? स्ट्रिंग को उप-वर्ग करने के बारे में कोई विचार, उस स्थिर उपयोगिता पद्धति को जोड़ना, और फिर हमेशा इसके बजाय MyString का उपयोग करना? अशक्त-सुरक्षित तुलना करने के लिए दो मापदंडों वाला एक स्थिर तरीका उस उपवर्ग में भी होना अच्छा होगा।
जॉन कूम्ब्स 1

7
ग्रूवी इसे सुरक्षित नेविगेशन ऑपरेटर ( groovy.codehaus.org/… ) के साथ थोड़ा आसान बनाता है ?.। यह nullString1?.equals(nullString2);पूरी तरह से अशक्त कथन में बदल जाएगा । हालाँकि, यह मदद नहीं करता है यदि आपके पास validString?.equals(nullString);- कि अभी भी एक अपवाद फेंकता है।
चार्ल्स वुड

5
जावा में अशक्त तार की तुलना करने के लिए लघु तरीके: stackoverflow.com/questions/11271554/…
वडज़िम

5
@JonCoombs Java सबक्लासिंग और स्वयं की विधि बनाने का समर्थन करता है। हालाँकि कुछ वर्गों को कुछ कारणों से अंतिम रूप से चिह्नित किया जाता है, स्ट्रिंग उनमें से एक है इसलिए हम विस्तार नहीं कर सकते हैं। हम अन्य वर्ग बना सकते हैं और वहां उपयोगिता वर्ग बना सकते हैं जो दो तर्कों को तर्क के रूप में लेते हैं और हमारे तर्क को वहां लागू करते हैं। इसके अलावा, कुछ अन्य पुस्तकालयों जैसे कि वसंत की जाँच करें और अपाचे वह विधियों का अच्छा संग्रह है, एक का उपयोग कर सकते हैं।
पैंथर

442

== तुलना वस्तु संदर्भ।

.equals() स्ट्रिंग मूल्यों की तुलना करता है।

कभी-कभी ==निम्नलिखित मामलों में, स्ट्रिंग मानों की तुलना करने का भ्रम देता है:

String a="Test";
String b="Test";
if(a==b) ===> true

इसका कारण यह है कि जब आप कोई स्ट्रिंग शाब्दिक बनाते हैं, तो JVM पहले स्ट्रिंग पूल में उस शाब्दिक के लिए खोज करता है, और यदि यह एक मैच पाता है, तो वही संदर्भ नए स्ट्रिंग को दिया जाएगा। इस वजह से, हम:

(a == b) ===> सत्य

                       String Pool
     b -----------------> "test" <-----------------a

हालाँकि, ==निम्न स्थिति में विफल रहता है:

String a="test";
String b=new String("test");
if (a==b) ===> false

इस मामले new String("test")में स्टेटमेंट के लिए नए स्ट्रीप को बनाया जाएगा, और यह संदर्भ दिया जाएगा b, इसलिए bस्टेप पूल में नहीं बल्कि हीप पर एक रेफरेंस दिया जाएगा।

अब aस्ट्रिंग में एक स्ट्रिंग bको इंगित कर रहा है जबकि ढेर पर एक स्ट्रिंग की ओर इशारा कर रहा है। उसके कारण हमें मिलता है:

if (a == b) ===> असत्य।

                String Pool
     "test" <-------------------- a

                   Heap
     "test" <-------------------- b

जबकि .equals()हमेशा तो यह दोनों ही मामलों में सच देता है स्ट्रिंग के मूल्य की तुलना:

String a="Test";
String b="Test";
if(a.equals(b)) ===> true

String a="test";
String b=new String("test");
if(a.equals(b)) ===> true

इसलिए उपयोग .equals()करना हमेशा बेहतर होता है।


3
.equals () दो उदाहरणों की तुलना करता है, हालांकि उनकी तुलना करने के लिए बराबर लागू किया जाता है। यह स्टर्लिंग के आउटपुट की तुलना कर सकता है या नहीं भी हो सकता है।
जैकब

3
@ जैकोब ऑब्जेक्ट क्लास .equals()विधि उदाहरणों (संदर्भों / पते) की तुलना करती है, जहां स्ट्रिंग क्लास .equals()विधियों की सामग्री (चार्ट) की तुलना करने के लिए ओवरराइड किया जाता है
सत्यदेव

1
अच्छा संकेत स्ट्रिंग पूल बनाम जावा ढेर अंतर के रूप में वे निश्चित रूप से समान नहीं हैं । स्ट्रिंग पूल में जावा Stringमेमोरी कैशप्रिंट को बचाने के लिए ऑब्जेक्ट्स को "कैश" करने की कोशिश करता है जैसा Stringकि अपरिवर्तनीय होने के लिए जाना जाता है (मुझे उम्मीद है, मैं इसे यहां सही ढंग से कहता हूं)। इसके अलावा stackoverflow.com/questions/3052442/…
रोलैंड

1
यह वह उत्तर है जिसकी मुझे तलाश थी।
वीएजी

क्या शानदार जवाब है!
15

223

==ऑपरेटर जांच करता है कि दो तार ठीक उसी वस्तु को देखने के लिए।

.equals()अगर दो तार एक ही मूल्य है विधि की जाँच करेगा।


5
आम तौर पर मैं दृढ़ता से अपाचे कॉमन्स लाइब्रेरी की सिफारिश करता हूं: commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/… , java.lang.String)
Marcin Erbel

179

जावा में स्ट्रिंग्स अपरिवर्तनीय हैं। इसका मतलब है कि जब भी आप स्ट्रिंग को बदलने / संशोधित करने का प्रयास करते हैं तो आपको एक नया उदाहरण मिलता है। आप मूल स्ट्रिंग को बदल नहीं सकते। ऐसा इसलिए किया गया है ताकि इन स्ट्रिंग इंस्टेंसेस को कैश किया जा सके। एक विशिष्ट कार्यक्रम में बहुत सारे स्ट्रिंग संदर्भ होते हैं और इन उदाहरणों को कैशिंग करने से मेमोरी फ़ुटप्रिंट कम हो सकता है और कार्यक्रम का प्रदर्शन बढ़ सकता है।

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

तो सवाल यह है कि अगर सिस्टम के सभी तार कैश हो गए हैं, तो कैसे ==झूठे रिटर्न आते हैं जबकि बराबर रिटर्न सही है? खैर, यह संभव है। यदि आप एक नया स्ट्रिंग बनाते हैं जैसे String str = new String("Testing")आप कैश में एक नया स्ट्रिंग बनाते हैं, भले ही कैश में पहले से ही समान सामग्री वाला स्ट्रिंग हो। संक्षेप "MyString" == new String("MyString")में हमेशा गलत लौटेगा।

जावा फ़ंक्शन इंटर्न () के बारे में भी बात करता है जो इसे स्ट्रिंग पर इस्तेमाल किया जा सकता है ताकि इसे कैश का हिस्सा बनाया जा सके "MyString" == new String("MyString").intern()

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


147
String a = new String("foo");
String b = new String("foo");
System.out.println(a == b); // prints false
System.out.println(a.equals(b)); // prints true

सुनिश्चित करें कि आप क्यों समझते हैं। यह इसलिए है क्योंकि ==तुलना केवल संदर्भों की तुलना करती है; equals()विधि सामग्री की एक तुलना चरित्र-दर-चरित्र करता है।

जब आप नया कॉल करते हैं aऔर b, प्रत्येक को एक नया संदर्भ मिलता है "foo"जो स्ट्रिंग तालिका में इंगित करता है। संदर्भ अलग हैं, लेकिन सामग्री समान है।


128

हाँ, यह बुरा है ...

==इसका मतलब है कि आपके दो स्ट्रिंग संदर्भ बिल्कुल एक ही वस्तु हैं। आपने सुना होगा कि यह मामला है क्योंकि जावा एक शाब्दिक तालिका (जो यह करता है) की तरह रखता है, लेकिन यह हमेशा ऐसा नहीं होता है। कुछ तार अलग-अलग तरीकों से लोड किए जाते हैं, अन्य तारों से निर्मित होते हैं, आदि, इसलिए आपको कभी भी यह नहीं मानना ​​चाहिए कि दो समान तार एक ही स्थान पर संग्रहीत हैं।

बराबरी आपके लिए असली तुलना करती है।


124

हां, ==स्ट्रिंग्स की तुलना करने के लिए बुरा है (वास्तव में कोई भी वस्तु, जब तक आप नहीं जानते कि वे विहित हैं)। ==सिर्फ वस्तु संदर्भों की तुलना करता है। .equals()समानता के लिए परीक्षण। स्ट्रिंग्स के लिए, अक्सर वे वही होंगे लेकिन जैसा कि आपने खोजा है, यह हमेशा की गारंटी नहीं है।


118

जावा में एक स्ट्रिंग पूल है जिसके तहत जावा स्ट्रिंग वस्तुओं के लिए मेमोरी आवंटन का प्रबंधन करता है। जावा में स्ट्रिंग पूल देखें

जब आप ==ऑपरेटर का उपयोग करके दो वस्तुओं की जांच (तुलना) करते हैं तो यह स्ट्रिंग-पूल में एड्रेस समानता की तुलना करता है। यदि दो स्ट्रिंग वस्तुओं का एक ही पता संदर्भ है तो यह वापस आ जाता है true, अन्यथा false। लेकिन अगर आप दो स्ट्रिंग वस्तुओं की सामग्री की तुलना करना चाहते हैं, तो आपको equalsविधि को ओवरराइड करना होगा ।

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

Example:
    stringObjectOne.equals(stringObjectTwo);

लेकिन मन यह स्ट्रिंग के मामले का सम्मान करता है। यदि आप मामले को असंवेदनशील चाहते हैं, तो आपको स्ट्रिंग क्लास के समसामयिक विधि के लिए जाना चाहिए।

चलो देखते हैं:

String one   = "HELLO"; 
String two   = "HELLO"; 
String three = new String("HELLO"); 
String four  = "hello"; 

one == two;   // TRUE
one == three; // FALSE
one == four;  // FALSE

one.equals(two);            // TRUE
one.equals(three);          // TRUE
one.equals(four);           // FALSE
one.equalsIgnoreCase(four); // TRUE

7
मैं देखता हूं कि यह बड़े सवाल का देर से जवाब है। क्या मैं पूछ सकता हूं कि यह क्या प्रदान करता है जो पहले से मौजूद उत्तरों में उल्लेखित नहीं है
9

6
@ मिस्टिक वह जोड़ा है equalsIgnoreCaseजो नवसिखुआ के लिए जानकारीपूर्ण हो सकता है।
अमित जी

103

मैं zacherates के जवाब से सहमत हूं।

लेकिन आप क्या कर सकते हैं intern()अपने गैर-शाब्दिक तार पर कॉल करें ।

Zacherates उदाहरण से:

// ... but they are not the same object
new String("test") == "test" ==> false 

यदि आप गैर-शाब्दिक स्ट्रिंग समानता को नजरअंदाज करते हैं true:

new String("test").intern() == "test" ==> true 

8
यह आमतौर पर एक अच्छा विचार नहीं है। इंटरस्टिंग अपेक्षाकृत महंगा है और (विरोधाभासी) >> वृद्धि << अपने JVM स्मृति पदचिह्न और जीसी लागत में वृद्धि कर सकते हैं। ज्यादातर मामलों में, ये ==स्ट्रिंग तुलना के लिए उपयोग करने से प्रदर्शन लाभ प्राप्त करते हैं ।
स्टीफन सी।

101

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

वस्तुओं की वास्तविक सामग्री (सहित String) की तुलना करने के लिए , किसी को equalsविधि का उपयोग करना चाहिए

यदि Stringउपयोग करने वाली दो वस्तुओं की तुलना ==होती है true, तो ऐसा इसलिए है क्योंकि Stringवस्तुओं को नजरबंद कर दिया गया था, और जावा वर्चुअल मशीन में एक ही उदाहरण के लिए कई संदर्भ बिंदु हैं String। किसी को यह अपेक्षा नहीं करनी चाहिए कि एक Stringवस्तु की तुलना उसी वस्तु से की जाए जिसका मूल्यांकन करने के लिए दूसरी Stringवस्तु का उपयोग ==किया जाता है true


99

.equals()एक वर्ग में डेटा की तुलना करता है (फ़ंक्शन को लागू किया जाता है)। ==सूचक स्थानों (स्मृति में ऑब्जेक्ट का स्थान) की तुलना करता है।

==यदि दोनों ऑब्जेक्ट्स (प्राथमिकताओं के बारे में नहीं पूछ रहे हों) तो सही वस्तु उदाहरण के लिए इंगित करता है। .equals()दो ऑब्जेक्ट जावा में एक ही डेटा बनाम होते हैं तो सच हैequals()==

वह आपकी मदद कर सकता है।


95

==एक संदर्भ समानता की जाँच करता है , चाहे 2 ऑब्जेक्ट (इस मामले में तार) स्मृति में एक ही ऑब्जेक्ट को संदर्भित करते हैं।

equals()विधि है कि क्या जाँच करेगा सामग्री या राज्यों 2 वस्तुओं की ही हैं।

स्पष्ट रूप ==से तेज़ है, लेकिन (शायद) कई मामलों में गलत परिणाम दे सकता है यदि आप यह बताना चाहते हैं कि क्या 2 Stringउसी पाठ को पकड़ते हैं।

निश्चित रूप से equals()विधि के उपयोग की सिफारिश की जाती है।

प्रदर्शन के बारे में चिंता मत करो। उपयोग करने के लिए प्रोत्साहित करने के लिए कुछ बातें String.equals():

  1. String.equals()संदर्भ समानता (उपयोग ==) के लिए पहले जांचों का कार्यान्वयन , और यदि संदर्भ द्वारा 2 तार समान हैं, तो आगे की गणना नहीं की जाती है!
  2. यदि 2 स्ट्रिंग संदर्भ समान नहीं हैं, String.equals()तो अगले स्ट्रिंग्स की लंबाई की जांच करेगा। यह भी एक तेज़ संचालन है क्योंकि Stringवर्ग स्ट्रिंग की लंबाई को संग्रहीत करता है, वर्ण या कोड बिंदुओं को गिनने की आवश्यकता नहीं है। यदि लंबाई भिन्न होती है, तो कोई और चेक नहीं किया जाता है, हम जानते हैं कि वे समान नहीं हो सकते हैं।
  3. यदि हमें यह मिल गया है तो केवल 2 स्ट्रिंग्स की सामग्री की वास्तव में तुलना की जाएगी, और यह एक शॉर्ट-हैंड तुलना होगी: सभी वर्णों की तुलना नहीं की जाएगी, अगर हम एक बेमेल चरित्र पाते हैं (2 स्ट्रिंग्स में एक ही स्थिति में ), अब और पात्रों की जाँच नहीं की जाएगी।

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


2
Obviously == is faster- वास्तव में कुछ भी करने से .equals(String)पहले पहले जांचों को लागू ==करना इसलिए मैं कहूंगा कि गति समान है।
रज्जल शज़ल

2
public boolean equals(Object anObject) { if (this == anObject) { return true; } ...
रज्जल शज़ल

82

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

इस ट्यूटोरियल में, मैं जावा स्ट्रिंग्स की तुलना करने के लिए कई अलग-अलग तरीकों का प्रदर्शन करूँगा, जो उस दृष्टिकोण के साथ शुरू होते हैं जिसका मैं ज्यादातर समय उपयोग करता हूं। इस जावा स्ट्रिंग तुलना ट्यूटोरियल के अंत में मैं यह भी चर्चा करूँगा कि जावा स्ट्रिंग्स की तुलना करते समय "==" ऑपरेटर काम क्यों नहीं करता है।

विकल्प 1: जावा स्ट्रिंग की बराबरी विधि के साथ तुलना (ज्यादातर समय का शायद 95%) मैं स्ट्रिंग स्ट्रिंग की तुलना जावा स्ट्रिंग वर्ग के समान विधि के साथ करता हूं, जैसे:

if (string1.equals(string2))

यह स्ट्रिंग बराबर पद्धति दो जावा स्ट्रिंग्स को देखती है, और यदि उनमें वर्णों की समान स्ट्रिंग है, तो उन्हें समान माना जाता है।

समान पद्धति के साथ एक त्वरित स्ट्रिंग तुलना उदाहरण पर एक नज़र डालते हुए, यदि निम्नलिखित परीक्षण चलाया गया था, तो दो तारों को समान नहीं माना जाएगा क्योंकि वर्ण बिल्कुल समान नहीं हैं (वर्णों का मामला अलग है):

String string1 = "foo";
String string2 = "FOO";

if (string1.equals(string2))
{
    // this line will not print because the
    // java string equals method returns false:
    System.out.println("The two strings are the same.")
}

लेकिन, जब दो तारों में वर्णों का एक ही तार होता है, तो समान विधि सही हो जाएगी, जैसा कि इस उदाहरण में है:

String string1 = "foo";
String string2 = "foo";

// test for equality with the java string equals method
if (string1.equals(string2))
{
    // this line WILL print
    System.out.println("The two strings are the same.")
}

विकल्प 2: स्ट्रींग इक्वलाइजेसनकोर विधि के साथ तुलना

कुछ स्ट्रिंग तुलना परीक्षणों में आप अनदेखा करना चाहेंगे कि क्या तार अपरकेस या लोअरकेस हैं। जब आप इस मामले-असंवेदनशील तरीके से समानता के लिए अपने तार का परीक्षण करना चाहते हैं, तो स्ट्रिंग क्लास की समसामयिक पद्धति का उपयोग करें, जैसे:

String string1 = "foo";
String string2 = "FOO";

 // java string compare while ignoring case
 if (string1.equalsIgnoreCase(string2))
 {
     // this line WILL print
     System.out.println("Ignoring case, the two strings are the same.")
 }

विकल्प 3: जावा स्ट्रिंग तुलना विधि के साथ तुलना

जावा स्ट्रिंग्स की तुलना करने के लिए एक तीसरा, कम सामान्य तरीका भी है, और यह स्ट्रिंग क्लास की तुलना विधि के साथ है। यदि दो तार बिल्कुल समान हैं, तो ComparTo विधि 0 (शून्य) का मान लौटा देगी। इस स्ट्रिंग तुलना दृष्टिकोण की तरह दिखने वाला एक त्वरित उदाहरण यहां दिया गया है:

String string1 = "foo bar";
String string2 = "foo bar";

// java string compare example
if (string1.compareTo(string2) == 0)
{
    // this line WILL print
    System.out.println("The two strings are the same.")
}

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

आप इस पर एक नज़र रखना चाह सकते हैं ==,। असमान (), तुलना (), और तुलना ()


5
स्ट्रिंग स्ट्रिंगल्स जैसे स्ट्रिंग स्ट्रिंग 1 = "फू बार"; स्ट्रिंग string2 = "फू बार"; आप सामग्री समानता का परीक्षण करने के लिए सीधे == ऑपरेटर का उपयोग कर सकते हैं
JAVA

1
Google ऐप्स स्क्रिप्ट में "ComparTo" नहीं है। मैंने "समान" की कोशिश की, यह एकमात्र समाधान था जो काम करता है ....
user3887038

77

समारोह:

public float simpleSimilarity(String u, String v) {
    String[] a = u.split(" ");
    String[] b = v.split(" ");

    long correct = 0;
    int minLen = Math.min(a.length, b.length);

    for (int i = 0; i < minLen; i++) {
        String aa = a[i];
        String bb = b[i];
        int minWordLength = Math.min(aa.length(), bb.length());

        for (int j = 0; j < minWordLength; j++) {
            if (aa.charAt(j) == bb.charAt(j)) {
                correct++;
            }
        }
    }

    return (float) (((double) correct) / Math.max(u.length(), v.length()));
}

परीक्षा:

String a = "This is the first string.";

String b = "this is not 1st string!";

// for exact string comparison, use .equals

boolean exact = a.equals(b);

// For similarity check, there are libraries for this
// Here I'll try a simple example I wrote

float similarity = simple_similarity(a,b);

6
यह अन्य उत्तरों से कैसे भिन्न है? और इसे आप क्यों सुझाते हैं
user151019

2
@ मर्क के बीच अंतर पर सवाल ==और equalsपहले से ही अन्य समाधानों से जवाब दिया गया था, मैंने बस एक अलग तरीके से तार की तुलना ढीले तरीके से करने की पेशकश की
खालिद.के।

77

==ऑपरेटर की जांच दो संदर्भों का उद्देश्य एक ही है या नहीं को इंगित करता है, तो। .equals()वास्तविक स्ट्रिंग सामग्री (मान) के लिए जाँच करें।

ध्यान दें कि .equals()विधि वर्ग Object(सभी वर्गों के सुपर क्लास) से संबंधित है। आपको कक्षा की आवश्यकता के अनुसार इसे ओवरराइड करने की आवश्यकता है, लेकिन स्ट्रिंग के लिए यह पहले से ही लागू है, और यह जांचता है कि दो तारों का एक ही मूल्य है या नहीं।

  • मामला एक

    String s1 = "Stack Overflow";
    String s2 = "Stack Overflow";
    s1 == s2;      //true
    s1.equals(s2); //true

    कारण: शून्य के बिना बनाए गए स्ट्रिंग शाब्दिक को ढेर के परमिट क्षेत्र में स्ट्रिंग पूल में संग्रहीत किया जाता है। तो s1 और s2 दोनों पूल में एक ही ऑब्जेक्ट को इंगित करते हैं।

  • केस 2

    String s1 = new String("Stack Overflow");
    String s2 = new String("Stack Overflow");
    s1 == s2;      //false
    s1.equals(s2); //true

    कारण: यदि आप newकीवर्ड का उपयोग करके एक स्ट्रिंग ऑब्जेक्ट बनाते हैं , तो ढेर पर एक अलग स्थान आवंटित किया जाता है।


53

==वस्तुओं के संदर्भ मूल्य की तुलना करता है जबकि कक्षा equals()में मौजूद विधि वस्तु java.lang.Stringकी सामग्री String(किसी अन्य वस्तु) से तुलना करती है।


15
नाइट पिकी नहीं होना चाहिए, लेकिन इसके लिए equals()विधि Stringवास्तव में Stringकक्षा में है, अंदर नहीं Object। डिफ़ॉल्ट equals()में Objectतुलना नहीं है कि सामग्री एक जैसी है, और वास्तव में सिर्फ सच लौटाता है जब संदर्भ में ही है।
जैकब स्कोन

1
@JacobSchoen: उपरोक्त लिंक अब काम नहीं करता क्योंकि ग्रेपकोड नीचे है। यहाँ समान कार्यान्वयन के लिए विकल्प है: [इनलाइन लिंक] ( zgrepcode.com/java/openjdk/10.0.2/java.base/java/lang/… )
अमनदीप सिंह

50

मुझे लगता है कि जब आप परिभाषित करते हैं Stringतो आप एक वस्तु को परिभाषित करते हैं। इसलिए आपको उपयोग करने की आवश्यकता है .equals()। जब आप आदिम डेटा प्रकारों का उपयोग करते हैं ==, तो आप String(और किसी भी वस्तु) का उपयोग करते हैं .equals()


7
"char []" एक आदिम डेटा प्रकार नहीं है! यह "चार" की एक सरणी है। और सरणियाँ आदिम डेटा प्रकार नहीं हैं।
क्रिश्चियन

48

यदि equals()विधि java.lang.Objectकक्षा में मौजूद है , और यह वस्तुओं की स्थिति की समानता के लिए जांच करने की उम्मीद है! इसका मतलब है, वस्तुओं की सामग्री। जबकि ==ऑपरेटर से अपेक्षा की जाती है कि वह वास्तविक वस्तु की जाँच कर सकता है या नहीं।

उदाहरण

दो अलग-अलग संदर्भ चर पर विचार करें, str1और str2:

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

यदि आप उपयोग करते हैं equals()

System.out.println((str1.equals(str2))?"TRUE":"FALSE");

आपको आउटपुट मिलेगा जैसे TRUEकि आप उपयोग करते हैं ==

System.out.println((str1==str2) ? "TRUE" : "FALSE");

अब आपको FALSEआउटपुट के रूप में मिलेगा , क्योंकि दोनों str1और str2दो अलग-अलग वस्तुओं की ओर इशारा कर रहे हैं , भले ही दोनों एक ही स्ट्रिंग सामग्री साझा करते हैं। इसकी वजह है कि new String()हर बार एक नई वस्तु बनाई जाती है।


43

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

String s1 = new String("abc");
String s2 = new String("abc");
System.out.println(s1 == s2); // It prints false (reference comparison)
System.out.println(s1.equals(s2)); // It prints true (content comparison)

40

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

एक महत्वपूर्ण बात यह है कि तार एक गांठ पूल में जमा हो जाते हैं, इसलिए एक बार एक स्ट्रिंग बनाने के बाद इसे हमेशा उसी पते पर एक कार्यक्रम में संग्रहीत किया जाता है। तार नहीं बदलते, वे अपरिवर्तनीय हैं। यही कारण है कि यदि आप करने के लिए स्ट्रिंग प्रसंस्करण की एक गंभीर मात्रा है, तो नियमित स्ट्रिंग संघनन का उपयोग करना एक बुरा विचार है। इसके बजाय आप StringBuilderप्रदान की गई कक्षाओं का उपयोग करेंगे । याद रखें कि इस स्ट्रिंग के पॉइंटर्स बदल सकते हैं और यदि आप यह देखने के लिए इच्छुक हैं कि क्या दो पॉइंटर्स समान थे, ==तो जाने का एक अच्छा तरीका होगा। स्ट्रिंग्स खुद नहीं करते।


2
"एक बार स्ट्रिंग बनाने के बाद इसे हमेशा एक ही पते पर एक कार्यक्रम में संग्रहीत किया जाता है" - यह फ्लैट-आउट गलत है। केवल संकलन-समय स्थिर स्ट्रिंग अभिव्यक्तियाँ (संभवतया final Stringचर शामिल ) और तार जो आपके प्रोग्राम को स्पष्ट रूप से इंटर्न्स में संग्रहीत करते हैं जिसे आप "गांठ पूल" कहते हैं। अन्य सभी Stringवस्तुएं कचरा संग्रहण के अधीन हैं, क्योंकि किसी भी अन्य प्रकार की वस्तु की तरह, उनके लिए अधिक जीवित संदर्भ नहीं हैं। इसके अलावा, जब पूरे इंटर्निंग तंत्र के काम करने के लिए अपरिहार्यता की आवश्यकता होती है, तो यह अन्यथा इसके लिए अप्रासंगिक है।
टेड होप

स्ट्रिंग की तुलना या तो समतुल्य या equalsIgnoreCase विधि के माध्यम से की जाती है जो वास्तव में स्ट्रिंग की सामग्री की तुलना करती है। लेकिन == साइन सिर्फ संदर्भ मूल्यों की जांच करें। स्ट्रिंग पूल से स्ट्रिंग शाब्दिक के लिए इस मामले के लिए ठीक काम करेगा। स्ट्रिंग s1 = नया स्ट्रिंग ("ए"); स्ट्रिंग s2 = नया स्ट्रिंग ("ए"); इस मामले में s1 == s2 गलत है, लेकिन s1.equals (s2) सत्य है।
शैलेंद्र सिंह

39

आप compareTo()दो स्ट्रिंग्स की तुलना करने के लिए विधि का उपयोग भी कर सकते हैं । यदि तुलना परिणाम 0 है, तो दो तार बराबर हैं, अन्यथा तुलना की जा रही तार बराबर नहीं हैं।

==संदर्भों की तुलना करता है और वास्तविक तारों की तुलना नहीं करता है। यदि आपने प्रत्येक स्ट्रिंग का उपयोग करके बनाया है, new String(somestring).intern()तो आप ==ऑपरेटर का उपयोग दो तारों की तुलना करने के लिए कर सकते हैं , अन्यथा बराबर () या तुलना करने के तरीकों का केवल उपयोग किया जा सकता है।


35

जावा में, जब 2 वस्तुओं की तुलना करने के लिए "==" ऑपरेटर का उपयोग किया जाता है, तो यह देखने के लिए जांचता है कि क्या ऑब्जेक्ट स्मृति में एक ही स्थान को संदर्भित करते हैं। दूसरे शब्दों में, यह देखने के लिए जांचता है कि क्या 2 ऑब्जेक्ट नाम मूल रूप से एक ही मेमोरी स्थान के संदर्भ हैं।

जावा स्ट्रिंग क्लास वास्तव में ऑब्जेक्ट क्लास में डिफ़ॉल्ट बराबर () कार्यान्वयन को ओवरराइड करता है - और यह विधि को ओवरराइड करता है ताकि यह केवल स्ट्रिंग्स के मूल्यों की जांच करता है, न कि मेमोरी में उनके स्थान। इसका मतलब यह है कि यदि आप 2 स्ट्रिंग वस्तुओं की तुलना करने के लिए बराबर () विधि कहते हैं, तो जब तक वर्णों का वास्तविक अनुक्रम समान है, दोनों वस्तुओं को समान माना जाता है।

==ऑपरेटर जांच करता है कि दो तार बिल्कुल वैसा ही उद्देश्य है।

.equals()विधि की जांच दो तार एक ही मूल्य है।


1
जब तक उनमें से एक अशक्त नहीं है, क्योंकि s.equals (s2) क्रैश होगा यदि s अशक्त है, जिससे तुलना विफल हो जाती है। बेशक, यह वास्तव में जवाब का खंडन नहीं करता है; यह सिर्फ एक चेतावनी है।
जॉन कूम्ब्स 1

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