1. জাভাতে বস্তুর তুলনা করা

জাভাতে, বস্তুকে রেফারেন্স এবং মান দ্বারা উভয়ই তুলনা করা যেতে পারে।

রেফারেন্স তুলনা

যদি দুটি ভেরিয়েবল একই বস্তুকে মেমরিতে নির্দেশ করে, তাহলে এই ভেরিয়েবলে সংরক্ষিত রেফারেন্স সমান। যদি আপনি সমতা অপারেটর ( ==) ব্যবহার করে এই ভেরিয়েবলগুলির তুলনা করেন, তাহলে আপনি সত্য পাবেন, এবং সেই ফলাফলটি বোঝা যায়। এখানে সবকিছু সহজ.

কোড কনসোল আউটপুট
Integer a = 5;
Integer b = a;
System.out.println(a == b);


true

মান দ্বারা তুলনা

কিন্তু আপনি প্রায়শই এমন পরিস্থিতির সম্মুখীন হতে পারেন যেখানে দুটি ভেরিয়েবল অভিন্ন দুটি স্বতন্ত্র বস্তুকে নির্দেশ করে। উদাহরণস্বরূপ, দুটি ভিন্ন স্ট্রিং অবজেক্ট যা একই পাঠ্য ধারণ করে।

বিভিন্ন বস্তু অভিন্ন কিনা তা নির্ধারণ করতে, equals()পদ্ধতিটি ব্যবহার করুন। উদাহরণ স্বরূপ:

কোড কনসোল আউটপুট
String a = new String("Hello");
String b = new String("Hello");
System.out.println(a == b);
System.out.println(a.equals(b));


false
true

পদ্ধতিটি equalsক্লাসের মধ্যে সীমাবদ্ধ নয় Stringপ্রতিটি ক্লাস এটি আছে.

এমনকি ক্লাস যেগুলো আপনি নিজে থেকে লেখেন, এবং এখানে কেন।



2. Objectক্লাস

জাভাতে সমস্ত ক্লাস ক্লাসের উত্তরাধিকারী Object। জাভা এর নির্মাতারা এই পদ্ধতির সাথে এসেছেন।

এবং যদি একটি ক্লাস Objectক্লাসের উত্তরাধিকারী হয়, তবে এটি ক্লাসের সমস্ত পদ্ধতি লাভ করে Object। এবং এটি উত্তরাধিকারের একটি প্রধান পরিণতি।

অন্য কথায়, প্রতিটি ক্লাসের ক্লাসের পদ্ধতি রয়েছে Object, এমনকি তাদের কোডে সেগুলি উল্লেখ না থাকলেও।

এই উত্তরাধিকারসূত্রে প্রাপ্ত পদ্ধতিগুলি বস্তুর তুলনা সম্পর্কিত পদ্ধতিগুলি অন্তর্ভুক্ত করে। এই equals()এবং hashCode()পদ্ধতি.

কোড বাস্তবে, আমাদের যা থাকবে তা এখানে:
class Person
{
   String name;
   int age;
}
class Person extends Object
{
   String name;
   int age;

   public boolean equals(Object obj)
   {
      return this == obj;
   }

   public int hashCode()
   {
      return address_of_object_in_memory; // This is the default implementation, but there may be a different implementation
   }
}

উপরের উদাহরণে, আমরা Personনাম এবং বয়সের পরামিতি সহ একটি সাধারণ ক্লাস তৈরি করেছি, কিন্তু একটি একক পদ্ধতি নয়। কিন্তু যেহেতু সমস্ত ক্লাস Objectক্লাসের উত্তরাধিকারী, Personক্লাসের স্বয়ংক্রিয়ভাবে দুটি পদ্ধতি রয়েছে:

পদ্ধতি বর্ণনা
boolean equals(Object obj)
বর্তমান বস্তু এবং পাস করা বস্তুর তুলনা করে
int hashCode()
বর্তমান বস্তুর হ্যাশকোড প্রদান করে

দেখা যাচ্ছে যে একেবারে প্রতিটি বস্তুর equalsপদ্ধতি রয়েছে এবং বিভিন্ন ধরণের বস্তু একে অপরের সাথে তুলনা করা যেতে পারে। এই ধরনের কোড কম্পাইল করবে এবং পুরোপুরি কাজ করবে।

কোড কনসোল আউটপুট
Integer a = 5;
String s = "Hello";
System.out.println(a.equals(s));
System.out.println(s.equals(a));


false
false
Object a = new Integer(5);
Object b = new Integer(5);
System.out.println(a.equals(b)) ;


true

3. equals()পদ্ধতি

পদ্ধতি equals(), ক্লাস থেকে উত্তরাধিকারসূত্রে প্রাপ্ত Object, পাস করা বস্তুর সাথে বর্তমান অবজেক্টের তুলনা করার জন্য সবচেয়ে সহজ অ্যালগরিদম প্রয়োগ করে: এটি শুধুমাত্র বস্তুর রেফারেন্সের সাথে তুলনা করে।

আপনি একই ফলাফল পাবেন যদি আপনি পদ্ধতিটি Personকল করার পরিবর্তে ভেরিয়েবলের তুলনা করেন equals()। উদাহরণ:

কোড কনসোল আউটপুট
Person a = new Person();
a.name = "Steve";

Person b = new Person();
b.name = "Steve";

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






false
false

যখন equalsপদ্ধতিটি কল করা হয় a, তখন এটি কেবলমাত্র ভেরিয়েবলে সংরক্ষিত রেফারেন্সের aসাথে ভেরিয়েবলে সংরক্ষিত রেফারেন্সের সাথে তুলনা করে b

যাইহোক, তুলনা Stringক্লাসের জন্য ভিন্নভাবে কাজ করে। কেন?

কারণ যারা Stringক্লাস তৈরি করেছে তারা তাদের নিজস্ব পদ্ধতির বাস্তবায়ন লিখেছে equals()

equals()পদ্ধতির বাস্তবায়ন

এখন ক্লাসে সমান পদ্ধতির নিজস্ব বাস্তবায়ন লিখি Person। আমরা 4টি প্রধান ক্ষেত্রে বিবেচনা করব।

গুরুত্বপূর্ণ:
কোন ক্লাস equalsপদ্ধতিটিকে ওভাররাইড করে না কেন, এটি সর্বদা একটি Objectবস্তুকে যুক্তি হিসাবে নেয়

দৃশ্যকল্প 1equals : যে বস্তুর উপর পদ্ধতিটি বলা হয় একই বস্তুটিও equalsপদ্ধতিতে পাস করা হয়। যদি বর্তমান অবজেক্ট এবং পাস করা বস্তুর রেফারেন্স সমান হয়, তবে পদ্ধতিটি অবশ্যই ফেরত দিতে হবে true। একটি বস্তু নিজেই সমান।

কোডে এটি এই মত দেখাবে:

কোড বর্ণনা
public boolean equals(Object obj)
{
   if (this == obj)
    return true;

   // The rest of the code of the equals method
}


রেফারেন্স তুলনা করুন

দৃশ্যকল্প 2 : nullপদ্ধতিতে পাস করা হয়েছে equals— আমাদের তুলনা করার কিছুই নেই। যে বস্তুটির উপর equalsপদ্ধতিটি বলা হয়েছে সেটি অবশ্যই শূন্য নয়, তাই আমাদের falseএই ক্ষেত্রে ফিরে আসতে হবে।

কোডে এটি এই মত দেখাবে:

কোড বর্ণনা
public boolean equals(Object obj)
{
   if (this == obj)
      return true;

   if (obj == null)
      return false;

   // The rest of the code of the equals method
}


রেফারেন্স তুলনা


পাস করা বস্তু কি null?

দৃশ্যকল্প 3 : একটি বস্তুর একটি রেফারেন্স যা একটি নয় Personপদ্ধতিতে পাস করা হয় equals। বস্তুটি কি Personঅ-বস্তুর সমান Person? এটি ক্লাসের বিকাশকারীর পক্ষে Personসিদ্ধান্ত নেওয়ার জন্য একটি প্রশ্ন যা সে চায়।

কিন্তু সাধারনত অবজেক্টকে সমান হিসাবে বিবেচনা করার জন্য একই শ্রেণীর হতে হবে। অতএব, যদি ক্লাসের একটি অবজেক্ট ছাড়া অন্য কিছু Personআমাদের সমান পদ্ধতিতে পাস করা হয়, তাহলে আমরা সর্বদা ফিরে আসব false। আপনি কিভাবে একটি বস্তুর ধরন পরীক্ষা করতে পারেন? এটা ঠিক — instanceofঅপারেটর ব্যবহার করে.

আমাদের নতুন কোড দেখতে কেমন তা এখানে:

কোড বর্ণনা
public boolean equals(Object obj)
{
   if (this == obj)
      return true;

   if (obj == null)
      return false;

   if (!(obj instanceof Person))
      return false;

   // The rest of the code of the equals method
}


রেফারেন্স তুলনা


পাস করা বস্তু কি null?


পাস করা বস্তু না হলে aPerson

Person4. দুটি বস্তুর তুলনা

আমরা কি শেষ করেছিলাম? যদি আমরা পদ্ধতির শেষে পৌঁছে থাকি, তাহলে আমাদের কাছে একটি Personবস্তুর রেফারেন্স আছে যা নয় null। তাই আমরা এটিকে a এ রূপান্তর করি Personএবং উভয় বস্তুর প্রাসঙ্গিক অভ্যন্তরীণ ডেটা তুলনা করি। এবং এটি আমাদের চতুর্থ দৃশ্যকল্প

কোড বর্ণনা
public boolean equals(Object obj)
{
   if (this == obj)
      return true;

   if (obj == null)
      return false;

   if (!(obj instanceof Person))
      return false;

   Person person = (Person) obj;

   // The rest of the code of the equals method
}


রেফারেন্স তুলনা


পাস করা বস্তু কি null?


যদি পাস করা বস্তুটি Person


টাইপকাস্টিং না হয়

Personএবং কিভাবে আপনি দুটি বস্তুর তুলনা করবেন ? nameএকই নাম ( ) এবং বয়স ( age) থাকলে তারা সমান । চূড়ান্ত কোড এই মত দেখাবে:

কোড বর্ণনা
public boolean equals(Object obj)
{
   if (this == obj)
      return true;

   if (obj == null)
      return false;

   if (!(obj instanceof Person))
      return false;

   Person person = (Person) obj;

   return this.name == person.name && this.age == person.age;
}


রেফারেন্স তুলনা


পাস করা বস্তু কি null?


যদি পাস করা বস্তুটি Person


টাইপকাস্টিং না হয়

কিন্তু এখানেই শেষ নয়.

প্রথমত, নামের ক্ষেত্রটি হল একটি , তাই আপনাকে পদ্ধতিটি Stringকল করে নামের ক্ষেত্রটির তুলনা করতে হবে ।equals

this.name.equals(person.name)

দ্বিতীয়ত, nameক্ষেত্রটি হতে পারে null: সেই ক্ষেত্রে, আপনি equalsএটিতে কল করতে পারবেন না। আপনার জন্য একটি অতিরিক্ত চেক প্রয়োজন null:

this.name != null && this.name.equals(person.name)

এটি বলেছে, যদি নামের ক্ষেত্রটি nullউভয় Personবস্তুতে থাকে, তবে নামগুলি এখনও সমান।

চতুর্থ দৃশ্যের জন্য কোড এই মত দেখতে হতে পারে:

Person person = (Person) obj;

if (this.age != person.age)
   return false;

if (this.name == null)
   return person.name == null;

return this.name.equals(person.name);


বয়স সমান না হলে,
অবিলম্বে return false

যদি this.nameসমান হয় , পদ্ধতি nullব্যবহার করে তুলনা করার কোন মানে নেই । equalsএখানে হয় দ্বিতীয় nameক্ষেত্রটি সমান null, বা এটি নয়।

পদ্ধতি ব্যবহার করে দুটি নামের ক্ষেত্রের তুলনা করুন equals


5. hashCode()পদ্ধতি

পদ্ধতিটি ছাড়াও equals, যা উভয় বস্তুর সমস্ত ক্ষেত্রের বিশদ তুলনা করার উদ্দেশ্যে করা হয়েছে, আরেকটি পদ্ধতি রয়েছে যা একটি অস্পষ্ট কিন্তু খুব দ্রুত তুলনার জন্য ব্যবহার করা যেতে পারে: hashCode().

কল্পনা করুন আপনি বর্ণানুক্রমিকভাবে হাজার হাজার শব্দের একটি তালিকা বাছাই করছেন, এবং আপনাকে বারবার জোড়া শব্দের তুলনা করতে হবে। এবং শব্দগুলি দীর্ঘ, প্রচুর অক্ষর সমন্বিত। সাধারণভাবে বলতে গেলে, এই ধরনের তুলনা খুব দীর্ঘ সময় লাগবে।

তবে এটি ত্বরান্বিত করা যেতে পারে। ধরুন আমাদের কাছে বিভিন্ন অক্ষর দিয়ে শুরু হওয়া শব্দ আছে - এটি অবিলম্বে স্পষ্ট যে তারা আলাদা। কিন্তু যদি তারা একই অক্ষর দিয়ে শুরু হয়, তাহলে আমরা এখনও বলতে পারি না যে ফলাফল কী হবে: শব্দগুলি সমান বা ভিন্ন হতে পারে।

পদ্ধতিটি hashCode()একই নীতি ব্যবহার করে কাজ করে। আপনি যদি এটিকে একটি বস্তুতে কল করেন তবে এটি কিছু সংখ্যা ফেরত দেয় - একটি শব্দের প্রথম অক্ষরের অনুরূপ। এই সংখ্যার নিম্নলিখিত বৈশিষ্ট্য রয়েছে:

  • অভিন্ন বস্তুর সবসময় একই হ্যাশকোড থাকে
  • বিভিন্ন বস্তুর একই হ্যাশকোড থাকতে পারে, বা তাদের হ্যাশকোড ভিন্ন হতে পারে
  • যদি বস্তুর বিভিন্ন হ্যাশকোড থাকে, তাহলে বস্তুগুলি অবশ্যই ভিন্ন

এটি আরও স্পষ্ট করার জন্য, আসুন এই বৈশিষ্ট্যগুলিকে শব্দের পরিপ্রেক্ষিতে রিফ্রেম করি:

  • অভিন্ন শব্দের সর্বদা একই প্রথম অক্ষর থাকে।
  • বিভিন্ন শব্দের একই প্রথম অক্ষর থাকতে পারে বা তাদের প্রথম অক্ষর ভিন্ন হতে পারে
  • যদি শব্দের প্রথম অক্ষর আলাদা থাকে, তবে শব্দগুলি অবশ্যই আলাদা

শেষ সম্পত্তি বস্তুর তুলনা ত্বরান্বিত করতে ব্যবহৃত হয়:

প্রথমত, দুটি বস্তুর হ্যাশকোড গণনা করা হয়। যদি এই হ্যাশকোডগুলি আলাদা হয়, তবে বস্তুগুলি অবশ্যই আলাদা, এবং তাদের তুলনা করার দরকার নেই।

কিন্তু যদি হ্যাশকোড একই হয়, তাহলে আমাদের এখনও সমান পদ্ধতি ব্যবহার করে বস্তুর তুলনা করতে হবে।



6. কোডে চুক্তি

উপরে বর্ণিত আচরণ অবশ্যই জাভাতে সমস্ত শ্রেণীর দ্বারা প্রয়োগ করা উচিত। সংকলনের সময়, বস্তুগুলি সঠিকভাবে তুলনা করা হয়েছে কিনা তা পরীক্ষা করার কোন উপায় নেই।

জাভা প্রোগ্রামারদের একটি সার্বজনীন চুক্তি রয়েছে যে তারা যদি সমান() পদ্ধতির নিজস্ব বাস্তবায়ন লিখে এবং এর ফলে স্ট্যান্ডার্ড ইমপ্লিমেন্টেশন (ক্লাসে Object) ওভাররাইড করে তবে তাদের অবশ্যই পদ্ধতির নিজস্ব বাস্তবায়ন hashCode()এমনভাবে লিখতে হবে যাতে পূর্বোক্ত নিয়মগুলি সন্তুষ্ট.

এই ব্যবস্থাকে চুক্তি বলা হয় ।

আপনি যদি আপনার ক্লাসে শুধুমাত্র equals()বা শুধুমাত্র hashCode()পদ্ধতিটি প্রয়োগ করেন, তাহলে আপনি চুক্তির চরম লঙ্ঘন করছেন (আপনি চুক্তি ভঙ্গ করেছেন)। এটা করবেন না।

যদি অন্য প্রোগ্রামাররা আপনার কোড ব্যবহার করে তবে এটি সঠিকভাবে কাজ নাও করতে পারে। আরো কি, আপনি কোড ব্যবহার করবেন যা উপরোক্ত চুক্তির আনুগত্যের উপর নির্ভর করে।

গুরুত্বপূর্ণ !

একটি উপাদান অনুসন্ধান করার সময়, সমস্ত জাভা সংগ্রহ প্রথমে বস্তুর হ্যাশকোড তুলনা করে, এবং শুধুমাত্র তারপর equalsপদ্ধতি ব্যবহার করে একটি তুলনা সম্পাদন করে।

এর মানে হল যে আপনি যদি আপনার নিজের ক্লাসকে একটি equalsপদ্ধতি দেন কিন্তু আপনি নিজের hashCode()পদ্ধতিটি না লিখেন বা আপনি এটি ভুলভাবে প্রয়োগ করেন, তাহলে সংগ্রহগুলি আপনার বস্তুর সাথে সঠিকভাবে কাজ নাও করতে পারে।

উদাহরণস্বরূপ, আপনি একটি তালিকায় একটি বস্তু যোগ করতে পারেন এবং তারপর contains()পদ্ধতিটি ব্যবহার করে এটি অনুসন্ধান করতে পারেন, কিন্তু সংগ্রহটি আপনার বস্তুটি খুঁজে নাও পেতে পারে।