CodeGym /Java Blog /এলোমেলো /জাভাতে স্ট্রিং এবং সমান তুলনা করুন
John Squirrels
লেভেল 41
San Francisco

জাভাতে স্ট্রিং এবং সমান তুলনা করুন

এলোমেলো দলে প্রকাশিত
ওহে! আজ আমরা একটি খুব গুরুত্বপূর্ণ এবং আকর্ষণীয় বিষয় নিয়ে কথা বলব, যথা, বস্তুর সাথে বস্তুর তুলনা (কম্পার স্ট্রিংস এবং ইকুয়ালস)। সুতরাং জাভাতে, কখন বস্তু 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টি ক্ষেত্রও থাকতে পারে, তবে তাদের তুলনা করলে তা মিথ্যা হবে। সব পরে, উল্লেখ car1 এবং car2দুটি ভিন্ন বস্তুর দিকে নির্দেশ করুন, অর্থাৎ দুটি ভিন্ন ঠিকানায়। এমন একটি পরিস্থিতি কল্পনা করুন যেখানে আপনি লোকেদের তুলনা করছেন। অবশ্যই, বিশ্বের কোথাও এমন একজন ব্যক্তি আছেন যিনি আপনার একই নাম, চোখের রঙ, বয়স, উচ্চতা, চুলের রঙ ইত্যাদি শেয়ার করেন৷ যা আপনাকে অনেক ক্ষেত্রে একই করে তোলে, কিন্তু আপনি এখনও যমজ নন — এবং আপনি স্পষ্টতই নন একই ব্যাক্তি.
সমান এবং স্ট্রিং তুলনা - 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% গ্যারান্টি দিতে হবে যে আমাদের সামনে যমজ সন্তান রয়েছে। কিন্তু আমাদের প্রোগ্রাম এবং == অপারেটর আমাদের বিপরীত বলে। কিভাবে আমরা এই আচরণ পরিবর্তন করব এবং নিশ্চিত করব যে প্রোগ্রামটি সঠিক ফলাফল বের করে যখন ডিএনএ মেলে? জাভা এর জন্য একটি বিশেষ পদ্ধতি রয়েছে: equals()toString() পদ্ধতির মতো , যা আমরা আগে আলোচনা করেছি, equals() অবজেক্ট ক্লাসের অন্তর্গত — জাভাতে সবচেয়ে গুরুত্বপূর্ণ ক্লাস, যে ক্লাস থেকে অন্য সব ক্লাস নেওয়া হয়। কিন্তু সমান()আমাদের প্রোগ্রামের আচরণ নিজেই পরিবর্তন করে না:

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() পদ্ধতিটি ওভাররাইড করে , আপনি সহজেই আপনার প্রয়োজনীয় বস্তু তুলনা যুক্তি তৈরি করতে পারেন। আসলে, আমরা শুধুমাত্র বস্তুর তুলনা স্পর্শ করেছি। আমাদের সামনে, এই বিষয়ে এখনও একটি বড় স্বতন্ত্র পাঠ রয়েছে (আপনি যদি আগ্রহী হন তবে আপনি এখনই এটিকে বাদ দিন)।

জাভা স্ট্রিং তুলনা

কেন আমরা অন্য সবকিছু থেকে আলাদাভাবে স্ট্রিং তুলনা বিবেচনা করছি? বাস্তবতা হল যে স্ট্রিংগুলি প্রোগ্রামিং এর নিজস্ব অধিকারে একটি বিষয়। প্রথমত, আপনি যদি লিখিত সমস্ত জাভা প্রোগ্রাম নেন, আপনি দেখতে পাবেন যে তাদের মধ্যে প্রায় 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
এবং যখনই আপনি 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.equals(s2));
   }
}
কনসোল আউটপুট: সত্য আকর্ষণীয়. আমরা নিশ্চিত যে s1 এবং s2 মেমরির বিভিন্ন এলাকায় নির্দেশ করে। কিন্তু 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));
   }
}
কনসোল আউটপুট: মিথ্যা অক্ষর-সংবেদনশীল তুলনার জন্য, স্ট্রিং ক্লাসে 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() পদ্ধতি

স্ট্রিং ক্লাসের আরও একটি জটিল পদ্ধতি রয়েছে: ইন্টার্ন( ) ; ইন্টার্ন () পদ্ধতি সরাসরি স্ট্রিং পুলের সাথে কাজ করে। আপনি যদি কিছু স্ট্রিং এ ইন্টার্ন() পদ্ধতি কল করেন:
  • এটি স্ট্রিং পুলে একটি মিলে যাওয়া স্ট্রিং আছে কিনা তা পরীক্ষা করে
  • যদি থাকে তবে এটি পুলের স্ট্রিংয়ের রেফারেন্স প্রদান করে
  • যদি না হয়, এটি স্ট্রিং পুলে স্ট্রিং যোগ করে এবং এটিতে একটি রেফারেন্স প্রদান করে।
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 যখন আমরা এই স্ট্রিংগুলিকে আগে ইন্টার্ন() ছাড়া তুলনা করি , ফলাফলটি মিথ্যা ছিল। এখন ইন্টার্ন() পদ্ধতি পরীক্ষা করে যে স্ট্রিংটি "কোডজিম জাভা শেখার জন্য সেরা সাইট!" স্ট্রিং পুলে আছে অবশ্যই, এটি: আমরা এটি দিয়ে তৈরি করেছি

String s1 = "CodeGym is the best website for learning Java!";
আমরা পরীক্ষা করি যে s1 এবং s2.intern() দ্বারা প্রত্যাবর্তিত রেফারেন্স মেমরির একই এলাকায় নির্দেশ করে কিনা। এবং অবশ্যই, তারা করে :) সংক্ষেপে, এই গুরুত্বপূর্ণ নিয়মটি মুখস্ত করুন এবং প্রয়োগ করুন: স্ট্রিং তুলনা করার জন্য সর্বদা সমান() পদ্ধতি ব্যবহার করুন! স্ট্রিং তুলনা করার সময়, আমরা প্রায় সবসময় রেফারেন্স, মেমরির ক্ষেত্র বা অন্য কিছুর পরিবর্তে তাদের অক্ষরগুলির তুলনা করতে চাই। equals () পদ্ধতি আপনার যা প্রয়োজন ঠিক তাই করে। আপনি যা শিখেছেন তা শক্তিশালী করার জন্য, আমরা আপনাকে আমাদের জাভা কোর্স থেকে একটি ভিডিও পাঠ দেখার পরামর্শ দিই
মন্তব্য
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION