CodeGym /Java Blog /यादृच्छिक /Java मध्ये स्ट्रिंग आणि समान तुलना करा
John Squirrels
पातळी 41
San Francisco

Java मध्ये स्ट्रिंग आणि समान तुलना करा

यादृच्छिक या ग्रुपमध्ये प्रकाशित केले
हाय! आज आपण एका अतिशय महत्त्वाच्या आणि मनोरंजक विषयाबद्दल बोलू, म्हणजे, वस्तूंशी वस्तूंची तुलना करणे (स्ट्रिंग्स आणि इक्वल्सची तुलना करा). तर जावा मध्ये, ऑब्जेक्ट A च्या बरोबरीने ऑब्जेक्ट B केव्हा होईल ? चला एक उदाहरण लिहिण्याचा प्रयत्न करूया:

public class Car {

   String model;
   int maxSpeed;

   public static void main(String[] args) {
      
       Car car1 = new Car();
       car1.model = "Ferrari";
       car1.maxSpeed = 300;

       Car car2 = new Car();
       car2.model = "Ferrari";
       car2.maxSpeed = 300;

       System.out.println(car1 == car2);
   }
}
कन्सोल आउटपुट: खोटे थांबा, थांबा. या दोन गाड्या समान का नाहीत? आम्ही त्यांना समान गुणधर्म नियुक्त केले, परंतु तुलनाचा परिणाम चुकीचा आहे. उत्तर सोपे आहे. == ऑपरेटर ऑब्जेक्ट संदर्भांची तुलना करतो, ऑब्जेक्ट गुणधर्मांची नाही. दोन ऑब्जेक्ट्समध्ये समान मूल्यांसह 500 फील्ड देखील असू शकतात, परंतु तरीही त्यांची तुलना करणे चुकीचे ठरेल. शेवटी, कार 1 आणि कार 2 चा संदर्भ आहेदोन भिन्न वस्तूंकडे निर्देश करा, म्हणजे दोन भिन्न पत्त्यांकडे. अशा परिस्थितीची कल्पना करा जिथे तुम्ही लोकांची तुलना करत आहात. नक्कीच, जगात कुठेतरी अशी व्यक्ती आहे जी तुमचे नाव, डोळ्यांचा रंग, वय, उंची, केसांचा रंग इ. सामायिक करते. जे तुम्हाला अनेक बाबतीत समान बनवते, परंतु तरीही तुम्ही जुळे नाही आहात — आणि तुम्ही नक्कीच नाही तीच व्यक्ती.
समान आणि स्ट्रिंग तुलना - 2
जेव्हा आपण दोन ऑब्जेक्ट्सची तुलना करण्यासाठी वापरतो तेव्हा == ऑपरेटर अंदाजे समान तर्क वापरतो. पण जर तुम्हाला तुमचा प्रोग्राम वेगळा लॉजिक वापरण्याची गरज असेल तर? उदाहरणार्थ, समजा तुमचा प्रोग्राम डीएनए विश्लेषण करतो. हे दोन लोकांच्या अनुवांशिक कोडची तुलना करते आणि ते जुळे आहेत की नाही हे निर्धारित करते.

public class Man {

   int geneticCode;

   public static void main(String[] args) {

       Man man1 = new Man();
       man1.geneticCode = 1111222233;

       Man man2 = new Man();
       man2.geneticCode = 1111222233;

       System.out.println(man1 == man2);
   }
}
कन्सोल आउटपुट: असत्य आम्हाला समान तार्किक परिणाम मिळतो (कारण आम्ही जास्त बदललो नाही), परंतु आता ते तर्क चांगले नाही! शेवटी, वास्तविक जीवनात, डीएनए विश्लेषणाने आम्हाला 100% हमी दिली पाहिजे की आमच्यासमोर जुळी मुले आहेत. पण आमचा प्रोग्राम आणि == ऑपरेटर आम्हाला उलट सांगतात. आम्ही हे वर्तन कसे बदलू आणि जेव्हा डीएनए जुळते तेव्हा प्रोग्राम योग्य परिणाम देईल याची खात्री कशी करायची? Java कडे यासाठी एक विशेष पद्धत आहे: equals() . toString() पद्धतीप्रमाणे , ज्याची आपण आधी चर्चा केली आहे, equals() हा ऑब्जेक्ट क्लासचा आहे — Java मधील सर्वात महत्त्वाचा क्लास, ज्या क्लासमधून इतर सर्व क्लास मिळतात. पण समान()आमच्या प्रोग्रामचे वर्तन स्वतःच बदलत नाही:

public class Man {

   String geneticCode;

   public static void main(String[] args) {

       Man man1 = new Man();
       man1.geneticCode = "111122223333";

       Man man2 = new Man();
       man2.geneticCode = "111122223333";

       System.out.println(man1.equals(man2));
   }
}
कन्सोल आउटपुट: असत्य तंतोतंत समान परिणाम, तर आम्हाला ही पद्धत कशासाठी आवश्यक आहे? :/ हे सर्व सोपे आहे. येथे समस्या अशी आहे की आम्ही सध्या ही पद्धत वापरत आहोत कारण ती ऑब्जेक्ट क्लासमध्ये लागू केली आहे. आणि जर आपण ऑब्जेक्ट क्लासच्या कोडमध्ये गेलो आणि पद्धतीची अंमलबजावणी पाहिली तर आपल्याला हे दिसेल:

public boolean equals(Object obj) {
   return (this == obj);
}
हेच कारण आहे की कार्यक्रमाचे वर्तन बदलले नाही! अगदी समान == ऑपरेटर (जो संदर्भांची तुलना करतो) ऑब्जेक्ट क्लासच्या equals() पद्धतीमध्ये वापरला जातो . परंतु या पद्धतीची युक्ती अशी आहे की आपण ते ओव्हरराइड करू शकतो. ओव्हरराइड करणे म्हणजे आमच्या मॅन क्लासमध्ये तुमची स्वतःची समान() पद्धत लिहा , आम्हाला आवश्यक वर्तन देऊन! सध्या, man1.equals(man2) मूलत: man1 == man2 च्या समतुल्य आहे हे आम्हाला आवडत नाही . या परिस्थितीत आम्ही काय करू ते येथे आहे:

public class Man { 

   int dnaCode; 

   public boolean equals(Man man) { 
       return this.dnaCode ==  man.dnaCode; 

   } 

   public static void main(String[] args) { 

       Man man1 = new Man(); 
       man1.dnaCode = 1111222233; 

       Man man2 = new Man(); 
       man2.dnaCode = 1111222233; 

       System.out.println(man1.equals(man2)); 

   } 
} 
कन्सोल आउटपुट: खरे आता आम्हाला पूर्णपणे भिन्न परिणाम मिळतो! आमची स्वतःची equals() पद्धत लिहून आणि मानक पद्धतीऐवजी ती वापरून, आम्ही योग्य वर्तन तयार केले आहे: आता जर दोन लोकांचा DNA समान असेल, तर प्रोग्राम अहवाल देतो "DNA विश्लेषणाने सिद्ध केले आहे की ते जुळे आहेत" आणि ते खरे परत येतात! तुमच्या वर्गांमध्ये equals() पद्धत ओव्हरराइड करून , तुम्हाला आवश्यक असलेले ऑब्जेक्ट तुलना लॉजिक तुम्ही सहजपणे तयार करू शकता. खरं तर, आम्ही फक्त ऑब्जेक्ट तुलना वर स्पर्श केला आहे. आमच्या पुढे, या विषयावर अजूनही एक मोठा धडा आहे (तुम्हाला स्वारस्य असल्यास तुम्ही आता त्यावर स्किम करा).

Java मधील स्ट्रिंगची तुलना करणे

आम्ही इतर सर्व गोष्टींपासून स्वतंत्रपणे स्ट्रिंग तुलना का विचार करत आहोत? वास्तविकता अशी आहे की प्रोग्रामिंगमध्ये स्ट्रिंग हा एक विषय आहे. प्रथम, तुम्ही लिहीलेले सर्व Java प्रोग्राम्स घेतल्यास, तुम्हाला आढळेल की त्यातील सुमारे 25% वस्तू स्ट्रिंग आहेत. त्यामुळे हा विषय अतिशय महत्त्वाचा आहे. दुसरे, स्ट्रिंग्सची तुलना करण्याची प्रक्रिया इतर वस्तूंपेक्षा खूप वेगळी आहे. एक साधे उदाहरण विचारात घ्या:

public class Main {

   public static void main(String[] args) {

       String s1 = "CodeGym is the best website for learning Java!";
       String s2 = new String("CodeGym is the best website for learning Java!");
       System.out.println(s1 == s2);
   }
}
कन्सोल आउटपुट: खोटे पण आम्हाला खोटे का मिळाले? शेवटी, स्ट्रिंग अगदी सारख्याच आहेत, शब्दासाठी शब्द :/ तुम्ही कारणाचा अंदाज लावला असेल: कारण == ऑपरेटर संदर्भांची तुलना करतो ! स्पष्टपणे, s1 आणि s2 चे मेमरीमध्ये वेगवेगळे पत्ते आहेत. जर तुम्हाला असे वाटले असेल, तर चला आमचे उदाहरण पुन्हा तयार करूया:

public class Main {

   public static void main(String[] args) {

       String s1 = "CodeGym is the best website for learning Java!";
       String s2 = "CodeGym is the best website for learning Java!";
       System.out.println(s1 == s2);
   }
}
आता आमच्याकडे पुन्हा दोन संदर्भ आहेत, परंतु परिणाम अगदी उलट आहे: कन्सोल आउटपुट: खरे हेल्पलेसली गोंधळलेले? चला काय चालले आहे ते शोधूया. == ऑपरेटर खरोखर मेमरी पत्त्यांची तुलना करतो. हे नेहमीच सत्य असते आणि तुम्हाला यात शंका घेण्याची गरज नाही. याचा अर्थ असा की जर s1 == s2 खरे असेल तर या दोन स्ट्रिंगचा पत्ता समान असेल. आणि खरंच हे खरं आहे! स्ट्रिंग संचयित करण्यासाठी मेमरीच्या एका विशेष क्षेत्राशी तुमची ओळख करून देण्याची वेळ आली आहे: स्ट्रिंग पूल
समान आणि स्ट्रिंग तुलना - 3
स्ट्रिंग पूल हे तुम्ही तुमच्या प्रोग्राममध्ये तयार केलेली सर्व स्ट्रिंग व्हॅल्यूज स्टोअर करण्यासाठी एक क्षेत्र आहे. ते का तयार केले गेले? आम्ही आधी म्हटल्याप्रमाणे, स्ट्रिंग्स सर्व वस्तूंच्या प्रचंड टक्केवारीचे प्रतिनिधित्व करतात. कोणताही मोठा प्रोग्राम खूप स्ट्रिंग तयार करतो. मेमरी जतन करण्यासाठी स्ट्रिंग पूल तयार केला गेला: स्ट्रिंग्स तेथे ठेवल्या जातात आणि नंतर तयार केलेल्या स्ट्रिंग मेमरीच्या समान क्षेत्राचा संदर्भ देतात - प्रत्येक वेळी अतिरिक्त मेमरी वाटप करण्याची आवश्यकता नाही. प्रत्येक वेळी तुम्ही स्ट्रिंग = "........" लिहिता तेव्हा प्रोग्राम स्ट्रिंग पूलमध्ये एकसारखी स्ट्रिंग आहे का ते तपासतो. तेथे असल्यास, नवीन स्ट्रिंग तयार केली जाणार नाही. आणि नवीन संदर्भ स्ट्रिंग पूलमधील समान पत्त्याकडे निर्देश करेल (जेथे समान स्ट्रिंग स्थित आहे). म्हणून जेव्हा आम्ही लिहिले

String s1 = "CodeGym is the best website for learning Java!";
String s2 = "CodeGym is the best website for learning Java!";
s2 s1 सारख्याच ठिकाणी बिंदू करतो . पहिले विधान स्ट्रिंग पूलमध्ये नवीन स्ट्रिंग तयार करते. दुसरे विधान s1 प्रमाणेच स्मृती क्षेत्राचा संदर्भ देते . तुम्ही आणखी 500 समान स्ट्रिंग बनवू शकता आणि परिणाम बदलणार नाही. एक मिनिट थांब. जर ते खरे असेल, तर हे उदाहरण आधी का चालले नाही?

public class Main {

   public static void main(String[] args) {

       String s1 = "CodeGym is the best website for learning Java!";
       String s2 = new String("CodeGym is the best website for learning Java!");
       System.out.println(s1 == s2);
   }
}
मला वाटते की तुमच्या अंतर्ज्ञानाने तुम्हाला आधीच कारण सांगितले आहे =) पुढील वाचण्यापूर्वी अंदाज लावण्याचा प्रयत्न करा. आपण पाहू शकता की या दोन तार वेगवेगळ्या प्रकारे घोषित केल्या गेल्या आहेत. एक नवीन ऑपरेटरसह आणि दुसरा त्याशिवाय. येथे कारण आहे. जेव्हा नवीन ऑपरेटर ऑब्जेक्ट तयार करण्यासाठी वापरला जातो, तेव्हा तो ऑब्जेक्टसाठी मेमरीचे नवीन क्षेत्र जबरदस्तीने वाटप करतो. आणि नवीन वापरून तयार केलेली स्ट्रिंग स्ट्रिंग पूलमध्ये संपत नाही — ती एक वेगळी वस्तू बनते, जरी त्याचा मजकूर स्ट्रिंग पूलमधील स्ट्रिंगशी पूर्णपणे जुळत असला तरीही. म्हणजेच, जर आपण खालील कोड लिहितो:

public class Main {

   public static void main(String[] args) {

       String s1 = "CodeGym is the best website for learning Java!";
       String s2 = "CodeGym is the best website for learning Java!";
       String s3 = new String("CodeGym is the best website for learning Java!");
   }
}
मेमरीमध्ये, हे असे दिसते:
समान आणि स्ट्रिंग तुलना - 4
आणि प्रत्येक वेळी तुम्ही नवीन वापरून नवीन ऑब्जेक्ट तयार करता तेव्हा , नवीन स्ट्रिंगमधील मजकूर समान असला तरीही, मेमरीचे नवीन क्षेत्र वाटप केले जाते! असे दिसते की आम्ही == ऑपरेटर शोधला आहे . पण आमच्या नवीन ओळखीचे, equals() पद्धतीचे काय ?

public class Main {

   public static void main(String[] args) {

       String s1 = "CodeGym is the best website for learning Java!";
       String s2 = new String("CodeGym is the best website for learning Java!");
       System.out.println(s1.equals(s2));
   }
}
कन्सोल आउटपुट: खरे मनोरंजक. आम्हाला खात्री आहे की s1 आणि s2 मेमरीमधील वेगवेगळ्या क्षेत्रांकडे निर्देश करतात. पण equals() पद्धत अजूनही आम्हाला सांगते की ते समान आहेत. का? लक्षात ठेवा आम्ही पूर्वी सांगितले होते की इक्वल्स() पद्धत आम्हाला पाहिजे त्या वस्तूंची तुलना करण्यासाठी ओव्हरराइड केली जाऊ शकते? स्ट्रिंग क्लासने त्यांनी हेच केले आहे . ते समान () ओव्हरराइड करतेपद्धत आणि संदर्भांची तुलना करण्याऐवजी, ते स्ट्रिंगमधील वर्णांच्या अनुक्रमांची तुलना करते. जर मजकूर समान असेल, तर ते कसे तयार केले गेले किंवा ते कोठे संग्रहित केले गेले याने काही फरक पडत नाही: स्ट्रिंग पूलमध्ये किंवा मेमरीच्या स्वतंत्र क्षेत्रामध्ये. तुलनेचा परिणाम खरा असेल. तसे, Java तुम्हाला केस-असंवेदनशील स्ट्रिंग तुलना करू देते. साधारणपणे, जर एका स्ट्रिंगमध्ये सर्व अप्परकेस अक्षरे असतील, तर तुलनाचा परिणाम चुकीचा असेल:

public class Main {

   public static void main(String[] args) {

       String s1 = "CodeGym is the best website for learning Java!";
       String s2 = new String("CODEGYM IS THE BEST WEBSITE FOR LEARNING JAVA!");
       System.out.println(s1.equals(s2));
   }
}
कन्सोल आउटपुट: खोटे केस-असंवेदनशील तुलनांसाठी, स्ट्रिंग क्लासमध्ये equalsIgnoreCase() पद्धत आहे. जर तुम्हाला अक्षराच्या केस ऐवजी विशिष्ट वर्णांच्या अनुक्रमांची तुलना करण्याची काळजी असेल तर तुम्ही ते वापरू शकता. उदाहरणार्थ, दोन पत्त्यांची तुलना करताना हे उपयुक्त ठरू शकते:

public class Main {

   public static void main(String[] args) {

       String address1 = "2311 Broadway Street, San Francisco";
       String address2 = new String("2311 BROADWAY STREET, SAN FRANCISCO");
       System.out.println(address1.equalsIgnoreCase(address2));
   }
}
या प्रकरणात, आम्ही स्पष्टपणे समान पत्त्याबद्दल बोलत आहोत, त्यामुळे equalsIgnoreCase() पद्धत वापरणे अर्थपूर्ण आहे.

String.intern() पद्धत

स्ट्रिंग क्लासमध्ये आणखी एक अवघड पद्धत आहे: intern() ; इंटर्न () पद्धत थेट स्ट्रिंग पूलसह कार्य करते. जर तुम्ही काही स्ट्रिंगवर इंटर्न() पद्धत कॉल केली तर:
  • स्ट्रिंग पूलमध्ये जुळणारी स्ट्रिंग आहे का ते तपासते
  • तेथे असल्यास, ते पूलमधील स्ट्रिंगचा संदर्भ देते
  • नसल्यास, ते स्ट्रिंग पूलमध्ये स्ट्रिंग जोडते आणि त्याचा संदर्भ देते.
new वापरून मिळवलेल्या स्ट्रिंग संदर्भावर इंटर्न() पद्धत वापरल्यानंतर , स्ट्रिंग पूलमधील स्ट्रिंग संदर्भाशी तुलना करण्यासाठी आपण == ऑपरेटर वापरू शकतो .

public class Main {

   public static void main(String[] args) {

       String s1 = "CodeGym is the best website for learning Java!";
       String s2 = new String("CodeGym is the best website for learning Java!");
       System.out.println(s1 == s2.intern());
   }
}
कन्सोल आऊटपुट: true जेव्हा आम्ही या स्ट्रिंग्सची पूर्वी intern() शिवाय तुलना केली , तेव्हा परिणाम चुकीचा होता. आता इंटर्न() पद्धत "कोडजिम जावा शिकण्यासाठी सर्वोत्तम साइट आहे का!" ही स्ट्रिंग तपासते. स्ट्रिंग पूलमध्ये आहे. अर्थात, ते आहे: आम्ही ते तयार केले

String s1 = "CodeGym is the best website for learning Java!";
आम्ही तपासतो की s1 आणि s2.intern() द्वारे परत आलेला संदर्भ मेमरीच्या समान क्षेत्राकडे निर्देशित करतो. आणि अर्थातच, ते करतात :) सारांशात, हा महत्त्वाचा नियम लक्षात ठेवा आणि लागू करा: स्ट्रिंगची तुलना करण्यासाठी नेहमी equals() पद्धत वापरा! स्ट्रिंग्सची तुलना करताना, आम्ही जवळजवळ नेहमीच संदर्भ, स्मृती क्षेत्र किंवा इतर कोणत्याही गोष्टीपेक्षा त्यांच्या वर्णांची तुलना करतो. equals () पद्धत तुम्हाला आवश्यक तेच करते. तुम्ही जे शिकलात ते बळकट करण्यासाठी, आम्ही तुम्हाला आमच्या Java कोर्समधील व्हिडिओ धडा पाहण्याची सूचना देतो
टिप्पण्या
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION