CodeGym /Java Blog /এলোমেলো /সমান এবং হ্যাশকোড পদ্ধতি: সেরা অনুশীলন
John Squirrels
লেভেল 41
San Francisco

সমান এবং হ্যাশকোড পদ্ধতি: সেরা অনুশীলন

এলোমেলো দলে প্রকাশিত
ওহে! আজ আমরা জাভাতে দুটি গুরুত্বপূর্ণ পদ্ধতি সম্পর্কে কথা বলব: equals()এবং hashCode(). এই প্রথমবার আমরা তাদের সাথে দেখা করিনি: CodeGym কোর্সটি সম্পর্কে একটি ছোট পাঠequals() দিয়ে শুরু হয় — যদি আপনি এটি ভুলে গিয়ে থাকেন বা এটি আগে না দেখে থাকেন তবে এটি পড়ুন... সমান এবং হ্যাশকোড পদ্ধতি: সেরা অনুশীলন - 1আজকের পাঠে, আমরা এই বিষয়ে কথা বলব বিস্তারিত এই ধারণা. এবং আমাকে বিশ্বাস করুন, আমাদের কিছু কথা বলার আছে! কিন্তু আমরা নতুনের দিকে যাওয়ার আগে, আসুন আমরা ইতিমধ্যে যা কভার করেছি তা রিফ্রেশ করি :) আপনি মনে রাখবেন, অপারেটর ব্যবহার করে দুটি বস্তুর তুলনা করা সাধারণত একটি খারাপ ধারণা, ==কারণ ==রেফারেন্স তুলনা করে। এখানে একটি সাম্প্রতিক পাঠ থেকে গাড়ির সাথে আমাদের উদাহরণ:

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);
   }
}
কনসোল আউটপুট:

false
মনে হচ্ছে আমরা দুটি অভিন্ন Carবস্তু তৈরি করেছি: দুটি গাড়ির বস্তুর সংশ্লিষ্ট ক্ষেত্রের মান একই, কিন্তু তুলনার ফলাফল এখনও মিথ্যা। আমরা ইতিমধ্যে কারণ জানি: car1এবং car2রেফারেন্স বিভিন্ন মেমরি ঠিকানা নির্দেশ করে, তাই তারা সমান নয়। কিন্তু আমরা এখনও দুটি বস্তুর তুলনা করতে চাই, দুটি উল্লেখ নয়। বস্তুর তুলনা করার জন্য সর্বোত্তম সমাধান হল equals()পদ্ধতি।

সমান() পদ্ধতি

আপনি মনে করতে পারেন যে আমরা এই পদ্ধতিটি স্ক্র্যাচ থেকে তৈরি করি না, বরং আমরা এটিকে ওভাররাইড করি: পদ্ধতিটি equals()ক্লাসে সংজ্ঞায়িত করা হয়েছে Object। এটি বলেছিল, এটির স্বাভাবিক আকারে, এটি খুব কম ব্যবহার করে:

public boolean equals(Object obj) {
   return (this == obj);
}
ক্লাসে পদ্ধতিটি এভাবেই equals()সংজ্ঞায়িত করা হয় Object। এটি আবার রেফারেন্সের তুলনা। কেন তারা এটার মত করে? আচ্ছা, ভাষার স্রষ্টারা কীভাবে জানবেন আপনার প্রোগ্রামের কোন বস্তু সমান এবং কোনটি নয়? :) এটি হল পদ্ধতির মূল বিষয় equals()— একটি শ্রেণির স্রষ্টা তিনিই নির্ধারণ করেন যে শ্রেণির বস্তুর সমতা পরীক্ষা করার সময় কোন বৈশিষ্ট্যগুলি ব্যবহার করা হবে। তারপরে আপনি equals()আপনার ক্লাসে পদ্ধতিটি ওভাররাইড করবেন। আপনি যদি "কোন বৈশিষ্ট্যগুলি নির্ধারণ করে" এর অর্থ পুরোপুরি বুঝতে না পারেন তবে আসুন একটি উদাহরণ বিবেচনা করি। এখানে একটি সাধারণ শ্রেণী একজন মানুষকে প্রতিনিধিত্ব করে: Man.

public class Man {

   private String noseSize;
   private String eyesColor;
   private String haircut;
   private boolean scars;
   private int dnaCode;

public Man(String noseSize, String eyesColor, String haircut, boolean scars, int dnaCode) {
   this.noseSize = noseSize;
   this.eyesColor = eyesColor;
   this.haircut = haircut;
   this.scars = scars;
   this.dnaCode = dnaCode;
}

   // Getters, setters, etc.
}
ধরুন আমরা এমন একটি প্রোগ্রাম লিখছি যা নির্ধারণ করতে হবে যে দুটি মানুষ অভিন্ন যমজ নাকি সাধারণ চেহারার। আমাদের পাঁচটি বৈশিষ্ট্য রয়েছে: নাকের আকার, চোখের রঙ, চুলের স্টাইল, দাগের উপস্থিতি এবং ডিএনএ পরীক্ষার ফলাফল (সরলতার জন্য, আমরা এটিকে একটি পূর্ণসংখ্যা কোড হিসাবে উপস্থাপন করি)। এই বৈশিষ্ট্যগুলির মধ্যে কোনটি আমাদের প্রোগ্রামটিকে অভিন্ন যমজ শনাক্ত করার অনুমতি দেবে বলে আপনি মনে করেন? সমান এবং হ্যাশকোড পদ্ধতি: সেরা অনুশীলন - 2অবশ্যই, শুধুমাত্র ডিএনএ পরীক্ষা একটি গ্যারান্টি প্রদান করতে পারে। দু'জনের চোখের রঙ, চুল কাটা, নাক এবং এমনকি দাগও একই হতে পারে — পৃথিবীতে প্রচুর মানুষ আছে এবং সেখানে কোনো ডপেলগ্যাঙ্গার নেই এমন গ্যারান্টি দেওয়া অসম্ভব। তবে আমাদের একটি নির্ভরযোগ্য প্রক্রিয়া দরকার: শুধুমাত্র একটি ডিএনএ পরীক্ষার ফলাফলই আমাদের একটি সঠিক উপসংহারে পৌঁছাতে দেবে। equals()আমাদের পদ্ধতির জন্য এর অর্থ কী ? আমরা এটা ওভাররাইড করতে হবেManক্লাস, আমাদের প্রোগ্রামের প্রয়োজনীয়তা বিবেচনায় নিয়ে। পদ্ধতিটি int dnaCodeদুটি বস্তুর ক্ষেত্রের তুলনা করা উচিত। যদি তারা সমান হয়, তাহলে বস্তুগুলি সমান।

@Override
public boolean equals(Object o) {
   Man man = (Man) o;
   return dnaCode == man.dnaCode;
}
এটি কি এতই সহজ? আসলে তা না. আমরা কিছু উপেক্ষা. আমাদের বস্তুর জন্য, আমরা শুধুমাত্র একটি ক্ষেত্র চিহ্নিত করেছি যা বস্তুর সমতা প্রতিষ্ঠার জন্য প্রাসঙ্গিক: dnaCode. এখন কল্পনা করুন যে আমাদের 1টি নয়, 50টি প্রাসঙ্গিক ক্ষেত্র রয়েছে। এবং যদি দুটি বস্তুর 50টি ক্ষেত্র সমান হয়, তাহলে বস্তুগুলি সমান। এমন দৃশ্যও সম্ভব। প্রধান সমস্যা হল 50টি ক্ষেত্রের তুলনা করে সমতা প্রতিষ্ঠা করা একটি সময়সাপেক্ষ এবং সম্পদ-নিবিড় প্রক্রিয়া। এখন কল্পনা করুন যে আমাদের ক্লাস ছাড়াও Man, আমাদের কাছে Womanঠিক একই ক্ষেত্রগুলির সাথে একটি শ্রেণী রয়েছে যা বিদ্যমান Man। যদি অন্য প্রোগ্রামার আমাদের ক্লাস ব্যবহার করে, তাহলে সে সহজেই এইরকম কোড লিখতে পারে:

public static void main(String[] args) {
  
   Man man = new Man(........); // A bunch of parameters in the constructor

   Woman woman = new Woman(.........); // The same bunch of parameters.

   System.out.println(man.equals(woman));
}
এই ক্ষেত্রে, ক্ষেত্রের মান পরীক্ষা করা অর্থহীন: আমরা সহজেই দেখতে পারি যে আমাদের দুটি ভিন্ন শ্রেণীর বস্তু রয়েছে, তাই তাদের সমান হতে পারে না! এর মানে আমাদের equals()তুলনা করা বস্তুর ক্লাসের তুলনা করে পদ্ধতিতে একটি চেক যোগ করা উচিত। এটা আমরা যে চিন্তা করা ভাল!

@Override
public boolean equals(Object o) {
   if (getClass() != o.getClass()) return false;
   Man man = (Man) o;
   return dnaCode == man.dnaCode;
}
কিন্তু আমরা হয়তো অন্য কিছু ভুলে গেছি? হুম... ন্যূনতম, আমাদের চেক করা উচিত যে আমরা কোনো বস্তুকে নিজের সাথে তুলনা করছি না! যদি রেফারেন্স A এবং B একই মেমরি ঠিকানা নির্দেশ করে, তাহলে তারা একই বস্তু, এবং আমাদের সময় নষ্ট করার এবং 50টি ক্ষেত্র তুলনা করার দরকার নেই।

@Override
public boolean equals(Object o) {
   if (this == o) return true;
   if (getClass() != o.getClass()) return false;
   Man man = (Man) o;
   return dnaCode == man.dnaCode;
}
এটির জন্য একটি চেক যোগ করাও ক্ষতি করে না null: কোন বস্তুর সমান হতে পারে না null। সুতরাং, যদি পদ্ধতির প্যারামিটারটি শূন্য হয়, তাহলে অতিরিক্ত চেকের কোন পয়েন্ট নেই। এই সমস্ত কিছু মাথায় রেখে, তারপর ক্লাসের equals()জন্য আমাদের পদ্ধতিটি Manএইরকম দেখায়:

@Override
public boolean equals(Object o) {
   if (this == o) return true;
   if (o == null || getClass() != o.getClass()) return false;
   Man man = (Man) o;
   return dnaCode == man.dnaCode;
}
আমরা উপরে উল্লিখিত সমস্ত প্রাথমিক চেক সঞ্চালন. দিনের শেষে, যদি:
  • আমরা একই শ্রেণীর দুটি বস্তুর তুলনা করছি
  • এবং তুলনামূলক বস্তু একই বস্তু নয়
  • এবং পাস করা বস্তুটি নয়null
...তারপর আমরা প্রাসঙ্গিক বৈশিষ্ট্যের তুলনা করতে এগিয়ে যাই। আমাদের জন্য, এর অর্থ হল dnaCodeদুটি বস্তুর ক্ষেত্র। পদ্ধতিটি ওভাররাইড করার সময় equals(), এই প্রয়োজনীয়তাগুলি পালন করতে ভুলবেন না:
  1. আত্ম - প্রতিফলন.

    যখন equals()পদ্ধতিটি ব্যবহার করা হয় কোন বস্তুকে নিজের সাথে তুলনা করার জন্য, এটি অবশ্যই সত্যে ফিরে আসবে।
    আমরা ইতিমধ্যে এই প্রয়োজনীয়তা মেনে চলেছি। আমাদের পদ্ধতি অন্তর্ভুক্ত:

    
    if (this == o) return true;
    

  2. প্রতিসাম্য।

    যদি a.equals(b) == true, তাহলে b.equals(a)ফিরতে হবে true
    আমাদের পদ্ধতি এই প্রয়োজনীয়তাকেও সন্তুষ্ট করে।

  3. ট্রানজিটিভিটি।

    যদি দুটি বস্তু তৃতীয় কোনো বস্তুর সমান হয়, তাহলে তাদের একে অপরের সমান হতে হবে।
    যদি a.equals(b) == trueএবং a.equals(c) == true, তারপর b.equals(c)সত্য ফিরে আসতে হবে.

  4. জেদ।

    equals()জড়িত ক্ষেত্র পরিবর্তন করা হয় শুধুমাত্র যখন ফলাফল পরিবর্তন করা আবশ্যক. যদি দুটি অবজেক্টের ডেটা পরিবর্তন না হয়, তবে এর ফলাফল equals()সর্বদা একই হতে হবে।

  5. সাথে বৈষম্য null

    যেকোন বস্তুর জন্য, a.equals(null)অবশ্যই মিথ্যা ফেরত দিতে হবে
    এটি শুধুমাত্র কিছু "উপযোগী সুপারিশ" এর একটি সেট নয়, বরং একটি কঠোর চুক্তি , যা ওরাকল ডকুমেন্টেশনে সেট করা হয়েছে

hashCode() পদ্ধতি

এখন পদ্ধতি সম্পর্কে কথা বলা যাক hashCode()। কেন এটা প্রয়োজন? ঠিক একই উদ্দেশ্যে - বস্তুর তুলনা করা। কিন্তু আমরা ইতিমধ্যে আছে equals()! কেন অন্য পদ্ধতি? উত্তরটি সহজ: কর্মক্ষমতা উন্নত করতে। একটি হ্যাশ ফাংশন, পদ্ধতিটি ব্যবহার করে জাভাতে উপস্থাপিত hashCode(), যেকোনো বস্তুর জন্য একটি নির্দিষ্ট-দৈর্ঘ্যের সংখ্যাসূচক মান প্রদান করে। জাভাতে, পদ্ধতিটি যেকোনো বস্তুর জন্য hashCode()একটি 32-বিট নম্বর ( ) প্রদান করে । intদুটি সংখ্যার তুলনা করা পদ্ধতিটি ব্যবহার করে দুটি বস্তুর তুলনা করার চেয়ে অনেক দ্রুত equals(), বিশেষ করে যদি সেই পদ্ধতিটি অনেকগুলি ক্ষেত্র বিবেচনা করে। আমাদের প্রোগ্রাম বস্তুর তুলনা করলে, হ্যাশ কোড ব্যবহার করে এটি করা অনেক সহজ। শুধুমাত্র যদি পদ্ধতির উপর ভিত্তি করে বস্তু সমান হয় তাহলে hashCode()তুলনাটি এগিয়ে যাবেequals()পদ্ধতি যাইহোক, এইভাবে হ্যাশ-ভিত্তিক ডেটা স্ট্রাকচার কাজ করে, উদাহরণস্বরূপ, পরিচিত HashMap! পদ্ধতি hashCode(), equals()পদ্ধতির মত, বিকাশকারী দ্বারা ওভাররাইড করা হয়। এবং ঠিক যেমন equals(), hashCode()পদ্ধতিটির অফিসিয়াল প্রয়োজনীয়তা ওরাকল ডকুমেন্টেশনে বানান করা আছে:
  1. যদি দুটি বস্তু সমান হয় (অর্থাৎ equals()পদ্ধতিটি সত্য হয়), তাহলে তাদের অবশ্যই একই হ্যাশ কোড থাকতে হবে।

    অন্যথায়, আমাদের পদ্ধতি অর্থহীন হবে। আমরা উপরে উল্লিখিত হিসাবে, hashCode()কর্মক্ষমতা উন্নত করার জন্য প্রথমে একটি চেক করা উচিত। equals()যদি হ্যাশ কোডগুলি ভিন্ন হয়, তাহলে চেকটি মিথ্যা ফেরত দেবে, যদিও বস্তুগুলি আসলে আমরা পদ্ধতিটি কীভাবে সংজ্ঞায়িত করেছি সে অনুযায়ী সমান।

  2. যদি hashCode()পদ্ধতিটি একই বস্তুতে একাধিকবার কল করা হয়, তবে এটি অবশ্যই প্রতিবার একই নম্বর ফেরত দেবে।

  3. নিয়ম 1 বিপরীত দিকে কাজ করে না। দুটি ভিন্ন বস্তুর একই হ্যাশ কোড থাকতে পারে।

তৃতীয় নিয়মটি একটু বিভ্রান্তিকর। এটা কিভাবে হতে পারে? ব্যাখ্যাটি বেশ সহজ। পদ্ধতিটি hashCode()একটি ফেরত দেয় int। An intএকটি 32-বিট সংখ্যা। এটির মানগুলির একটি সীমিত পরিসর রয়েছে: -2,147,483,648 থেকে +2,147,483,647 পর্যন্ত। অন্য কথায়, একটির জন্য মাত্র 4 বিলিয়নেরও বেশি সম্ভাব্য মান রয়েছে int। এখন কল্পনা করুন যে আপনি পৃথিবীতে বসবাসকারী সমস্ত মানুষের তথ্য সংরক্ষণ করার জন্য একটি প্রোগ্রাম তৈরি করছেন। প্রতিটি ব্যক্তি তার নিজস্ব বস্তুর সাথে মিলিত হবে Person(শ্রেণীর অনুরূপ Man)। গ্রহে ~ 7.5 বিলিয়ন মানুষ বাস করে। অন্য কথায়, রূপান্তর করার জন্য আমরা যতই চতুর অ্যালগরিদম লিখি না কেনPersonএকটি int অবজেক্ট, আমরা সহজভাবে যথেষ্ট সম্ভাব্য সংখ্যা নেই. আমরা শুধুমাত্র 4.5 বিলিয়ন সম্ভাব্য int মান আছে, কিন্তু এর চেয়ে অনেক বেশি মানুষ আছে. এর মানে হল যে আমরা যতই চেষ্টা করি না কেন, কিছু ভিন্ন লোকের একই হ্যাশ কোড থাকবে। যখন এটি ঘটে (হ্যাশ কোড দুটি ভিন্ন বস্তুর জন্য মিলে যায়) তখন আমরা একে সংঘর্ষ বলি। পদ্ধতিটি ওভাররাইড করার সময় hashCode(), প্রোগ্রামারের উদ্দেশ্যগুলির মধ্যে একটি হল সম্ভাব্য সংঘর্ষের সংখ্যা কমিয়ে আনা। এই সব নিয়মের হিসাব-নিকাশ, hashCode()ক্লাসে পদ্ধতি কেমন হবে Person? এটার মত:

@Override
public int hashCode() {
   return dnaCode;
}
বিস্মিত? :) আপনি যদি প্রয়োজনীয়তাগুলি দেখেন তবে আপনি দেখতে পাবেন যে আমরা সেগুলি সব মেনে চলি। যে অবজেক্টগুলির জন্য আমাদের equals()পদ্ধতি সত্য ফেরত দেয় তাও অনুযায়ী সমান হবে hashCode()। যদি আমাদের দুটি Personঅবজেক্ট সমান হয় equals(অর্থাৎ তাদের একই থাকে dnaCode), তাহলে আমাদের পদ্ধতি একই সংখ্যা প্রদান করে। আসুন আরও কঠিন উদাহরণ বিবেচনা করি। ধরুন আমাদের প্রোগ্রামে গাড়ি সংগ্রহকারীদের জন্য বিলাসবহুল গাড়ি নির্বাচন করা উচিত। সংগ্রহ করা অনেক অদ্ভুততার সাথে একটি জটিল শখ হতে পারে। একটি নির্দিষ্ট 1963 গাড়ির দাম 1964 গাড়ির চেয়ে 100 গুণ বেশি হতে পারে। একটি 1970 লাল গাড়ি একই বছরের একই ব্র্যান্ডের একটি নীল গাড়ির চেয়ে 100 গুণ বেশি খরচ করতে পারে। সমান এবং হ্যাশকোড পদ্ধতি: সর্বোত্তম অনুশীলন - 4আমাদের পূর্ববর্তী উদাহরণে, Personক্লাসের সাথে, আমরা বেশিরভাগ ক্ষেত্র (অর্থাৎ মানুষের বৈশিষ্ট্য) তুচ্ছ হিসাবে বাতিল করে দিয়েছি এবং শুধুমাত্র ব্যবহার করেছিdnaCodeতুলনা ক্ষেত্র আমরা এখন একটি খুব ইডিওসিঙ্ক্রাটিক রাজ্যে কাজ করছি, যেখানে কোনও তুচ্ছ বিবরণ নেই! এখানে আমাদের LuxuryAutoক্লাস:

public class LuxuryAuto {

   private String model;
   private int manufactureYear;
   private int dollarPrice;

   public LuxuryAuto(String model, int manufactureYear, int dollarPrice) {
       this.model = model;
       this.manufactureYear = manufactureYear;
       this.dollarPrice = dollarPrice;
   }

   // ...getters, setters, etc.
}
এখন আমরা আমাদের তুলনা সব ক্ষেত্র বিবেচনা করা আবশ্যক. যেকোন ভুলের জন্য একজন ক্লায়েন্টকে কয়েক হাজার ডলার খরচ হতে পারে, তাই অত্যধিক নিরাপদ হওয়া ভালো হবে:

@Override
public boolean equals(Object o) {
   if (this == o) return true;
   if (o == null || getClass() != o.getClass()) return false;

   LuxuryAuto that = (LuxuryAuto) o;

   if (manufactureYear != that.manufactureYear) return false;
   if (dollarPrice != that.dollarPrice) return false;
   return model.equals(that.model);
}
আমাদের equals()পদ্ধতিতে, আমরা আগে যে সমস্ত চেকের কথা বলেছিলাম সেগুলি আমরা ভুলে যাইনি। কিন্তু এখন আমরা আমাদের বস্তুর তিনটি ক্ষেত্র প্রতিটি তুলনা. এই প্রোগ্রামের জন্য, আমাদের প্রয়োজন পরম সমতা, অর্থাৎ প্রতিটি ক্ষেত্রের সমতা। কি সম্পর্কে hashCode?

@Override
public int hashCode() {
   int result = model == null ? 0 : model.hashCode();
   result = result + manufactureYear;
   result = result + dollarPrice;
   return result;
}
modelআমাদের ক্লাসের ক্ষেত্রটি একটি স্ট্রিং । এটি সুবিধাজনক, কারণ Stringক্লাসটি ইতিমধ্যে hashCode()পদ্ধতিটিকে ওভাররাইড করে। আমরা modelক্ষেত্রের হ্যাশ কোড গণনা করি এবং তারপরে এটিতে অন্যান্য দুটি সংখ্যাসূচক ক্ষেত্রের যোগফল যোগ করি। জাভা ডেভেলপারদের একটি সহজ কৌশল রয়েছে যা তারা সংঘর্ষের সংখ্যা কমাতে ব্যবহার করে: একটি হ্যাশ কোড গণনা করার সময়, একটি বিজোড় প্রাইম দ্বারা মধ্যবর্তী ফলাফলকে গুণ করুন। সর্বাধিক ব্যবহৃত সংখ্যাটি হল 29 বা 31৷ আমরা এখনই গাণিতিক সূক্ষ্মতাগুলি নিয়ে আলোচনা করব না, তবে ভবিষ্যতে মনে রাখবেন যে মধ্যবর্তী ফলাফলগুলিকে যথেষ্ট বড় বিজোড় সংখ্যা দ্বারা গুণ করা হ্যাশ ফাংশনের ফলাফলগুলিকে "প্রসারিত" করতে সহায়তা করে এবং, ফলস্বরূপ, একই হ্যাশ কোড সহ বস্তুর সংখ্যা হ্রাস করুন। hashCode()লাক্সারিঅটোতে আমাদের পদ্ধতির জন্য , এটি দেখতে এইরকম হবে:

@Override
public int hashCode() {
   int result = model == null ? 0 : model.hashCode();
   result = 31 * result + manufactureYear;
   result = 31 * result + dollarPrice;
   return result;
}
আপনি StackOverflow-এর এই পোস্টে , সেইসাথে Joshua Bloch-এর Effective Java বইটিতে এই প্রক্রিয়ার সমস্ত জটিলতা সম্পর্কে আরও পড়তে পারেন । অবশেষে, আরও একটি গুরুত্বপূর্ণ বিষয় যা উল্লেখ করার মতো। প্রতিবার যখন আমরা equals()এবং hashCode()পদ্ধতি ওভাররড করি, আমরা নির্দিষ্ট কিছু দৃষ্টান্ত ক্ষেত্র নির্বাচন করেছি যা এই পদ্ধতিগুলিতে বিবেচনা করা হয়। এই পদ্ধতিগুলি একই ক্ষেত্র বিবেচনা করে। কিন্তু আমরা বিভিন্ন ক্ষেত্রে বিবেচনা করতে পারি equals()এবং hashCode()? প্রযুক্তিগতভাবে, আমরা পারি। কিন্তু এটি একটি খারাপ ধারণা, এবং এখানে কেন:

@Override
public boolean equals(Object o) {
   if (this == o) return true;
   if (o == null || getClass() != o.getClass()) return false;

   LuxuryAuto that = (LuxuryAuto) o;

   if (manufactureYear != that.manufactureYear) return false;
   return dollarPrice == that.dollarPrice;
}

@Override
public int hashCode() {
   int result = model == null ? 0 : model.hashCode();
   result = 31 * result + manufactureYear;
   result = 31 * result + dollarPrice;
   return result;
}
এখানে ক্লাসের জন্য আমাদের equals()এবং পদ্ধতি রয়েছে । পদ্ধতিটি অপরিবর্তিত ছিল, তবে আমরা পদ্ধতি থেকে ক্ষেত্রটি সরিয়ে দিয়েছি । যখন পদ্ধতি দুটি বস্তুর তুলনা করে তখন মডেলটি আর ব্যবহৃত বৈশিষ্ট্য নয় । কিন্তু হ্যাশ কোড গণনা করার সময়, সেই ক্ষেত্রটি এখনও বিবেচনায় নেওয়া হয়। এর ফলে আমরা কী পাই? আসুন দুটি গাড়ি তৈরি করি এবং খুঁজে বের করি! hashCode()LuxuryAutohashCode()modelequals()equals()

public class Main {

   public static void main(String[] args) {

       LuxuryAuto ferrariGTO = new LuxuryAuto("Ferrari 250 GTO", 1963, 70000000);
       LuxuryAuto ferrariSpider = new LuxuryAuto("Ferrari 335 S Spider Scaglietti", 1963, 70000000);

       System.out.println("Are these two objects equal to each other?");
       System.out.println(ferrariGTO.equals(ferrariSpider));

       System.out.println("What are their hash codes?");
       System.out.println(ferrariGTO.hashCode());
       System.out.println(ferrariSpider.hashCode());
   }
}

Are these two objects equal to each other? 
true 
What are their hash codes? 
-1372326051 
1668702472
ত্রুটি! বিভিন্ন ক্ষেত্র equals()এবং hashCode()পদ্ধতি ব্যবহার করে, আমরা তাদের জন্য প্রতিষ্ঠিত চুক্তি লঙ্ঘন করেছি! পদ্ধতি অনুসারে সমান দুটি বস্তুর equals()একই হ্যাশ কোড থাকতে হবে। আমরা তাদের জন্য বিভিন্ন মান পেয়েছি। এই জাতীয় ত্রুটিগুলি একেবারে অবিশ্বাস্য পরিণতির দিকে নিয়ে যেতে পারে, বিশেষ করে যখন হ্যাশ ব্যবহার করে এমন সংগ্রহগুলির সাথে কাজ করা। ফলস্বরূপ, যখন আপনি ওভাররাইড করবেন equals()এবং hashCode(), আপনার একই ক্ষেত্র বিবেচনা করা উচিত। এই পাঠটি বরং দীর্ঘ ছিল, কিন্তু আপনি আজ অনেক কিছু শিখেছেন! :) এখন কাজগুলি সমাধানে ফিরে আসার সময়!
মন্তব্য
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION