"এখন আমি আপনাকে এমন কিছু পদ্ধতি সম্পর্কে বলব যা ঠিক তেমনই সহায়ক:  equals(Object o) & hashCode() ।"

"আপনি সম্ভবত ইতিমধ্যেই মনে রেখেছেন যে, জাভাতে, রেফারেন্স ভেরিয়েবলের তুলনা করার সময় বস্তুর সাথে তুলনা করা হয় না, বরং বস্তুর রেফারেন্সের সাথে তুলনা করা হয়।"

কোড ব্যাখ্যা
Integer i = new Integer(1);
Integer j = new Integer(1);
System.out.println(i==j);
আমি j এর সমান নয়
ভেরিয়েবলগুলি বিভিন্ন বস্তুকে নির্দেশ করে।
যদিও বস্তু একই তথ্য ধারণ করে.
Integer i = new Integer(1);
Integer j = i;
System.out.println(i==j);
আমি জে সমান। ভেরিয়েবল একই বস্তুর একটি রেফারেন্স ধারণ করে।

"হ্যাঁ, এটা মনে আছে।"

সমান  _

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

"এবং এটা কিভাবে করে?"

"এটি সবই toString() পদ্ধতির অনুরূপ।"

অবজেক্ট ক্লাসের সমান পদ্ধতির নিজস্ব বাস্তবায়ন রয়েছে, যা সহজভাবে রেফারেন্সের তুলনা করে:

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

"দারুণ... আবার সেই দিকে ফিরে আসি, আমরা কি?"

"আপনার চিবুক উপরে রাখুন! এটা আসলে খুব কঠিন।"

"এই পদ্ধতিটি বিকাশকারীদের তাদের নিজস্ব ক্লাসে এটিকে ওভাররাইট করার অনুমতি দেওয়ার জন্য তৈরি করা হয়েছিল। সর্বোপরি, শুধুমাত্র একটি ক্লাসের বিকাশকারীই জানেন যে কোন ডেটা প্রাসঙ্গিক এবং কোনটি তুলনা করার সময় নয়।"

"আপনি একটি উদাহরণ প্রদান করতে পারেন?"

"অবশ্যই। ধরুন আমাদের একটি ক্লাস আছে যা গাণিতিক ভগ্নাংশকে প্রতিনিধিত্ব করে। এটি দেখতে এরকম হবে:"

উদাহরণ:
class Fraction
{
private int numerator;
private int denominator;
Fraction(int numerator, int denominator)
{
this.numerator  = numerator;
this.denominator = denominator;
}public boolean equals(Object obj)
{
if (obj==null)
return false;

if (obj.getClass() != this.getClass() )
return false;

Fraction other = (Fraction) obj;
return this.numerator* other.denominator == this.denominator * other.numerator;
}
}
উদাহরণ পদ্ধতি কল:
Fraction one = new Fraction(2,3);
Fraction two = new Fraction(4,6);
System.out.println(one.equals(two));
পদ্ধতি কল সত্য ফিরে আসবে।
ভগ্নাংশ 2/3 ভগ্নাংশ 4/6 সমান

"এখন, এই উদাহরণটি ব্যবচ্ছেদ করা যাক।"

"আমরা সমান পদ্ধতিকে অগ্রাহ্য করেছি, তাই ভগ্নাংশ বস্তুর নিজস্ব বাস্তবায়ন থাকবে।

"পদ্ধতিতে বেশ কয়েকটি চেক রয়েছে:"

" 1)  যদি তুলনা করার জন্য পাস করা বস্তুটি নাল হয় , তাহলে বস্তুগুলি সমান নয়। আপনি যদি একটি বস্তুর সমান পদ্ধতিকে কল করতে পারেন, তাহলে এটি অবশ্যই নাল নয় ।"

" 2)  একটি শ্রেণী তুলনা৷ যদি বস্তুগুলি বিভিন্ন শ্রেণীর উদাহরণ হয়, তবে আমরা সেগুলি তুলনা করার চেষ্টা করব না৷ পরিবর্তে, আমরা অবিলম্বে রিটার্ন মিথ্যা ব্যবহার করব যাতে বোঝানো যায় যে এগুলি ভিন্ন বস্তু৷"

" 3)  সবাই দ্বিতীয় গ্রেড থেকে মনে রেখেছে যে 2/3 সমান 4/6। কিন্তু আপনি কিভাবে এটি পরীক্ষা করবেন?"

2/3 == 4/6
আমরা উভয় পক্ষকে উভয় ভাজক (6 এবং 3) দ্বারা গুণ করি এবং আমরা পাই:
6 * 2 == 4 * 3
12 == 12
সাধারণ নিয়ম:

a / b == c / d হলে
a
* d == c * b

"তদনুসারে, সমান পদ্ধতির তৃতীয় অংশে , আমরা পাস করা বস্তুটিকে একটি ভগ্নাংশে নিক্ষেপ করি এবং ভগ্নাংশের তুলনা করি।"

"বুঝলাম। যদি আমরা সহজভাবে লবের সাথে লব এবং হরকে হর এর সাথে তুলনা করি, তাহলে 2/3 4/6 এর সমান নয়।"

"এখন আমি বুঝতে পেরেছি আপনি কি বোঝাতে চেয়েছিলেন যখন আপনি বলেছিলেন যে শুধুমাত্র একটি ক্লাসের বিকাশকারীই জানেন কিভাবে এটি সঠিকভাবে তুলনা করতে হয়।"

"হ্যাঁ, কিন্তু এটি মাত্র অর্ধেক গল্প।  আরেকটি পদ্ধতি আছে: হ্যাশকোড()। "

"সমান পদ্ধতি সম্পর্কে সবকিছুই এখন বোধগম্য, কিন্তু কেন আমাদের  হ্যাশকোড () দরকার? "

" দ্রুত তুলনা করার জন্য হ্যাশকোড পদ্ধতি প্রয়োজন।"

" ইকুয়ালস পদ্ধতির একটি প্রধান নেতিবাচক দিক রয়েছে: এটি খুব ধীরে ধীরে কাজ করে। ধরুন আপনার লক্ষ লক্ষ উপাদানের একটি সেট আছে এবং এটিতে একটি নির্দিষ্ট বস্তু রয়েছে কিনা তা পরীক্ষা করতে হবে। আপনি কীভাবে এটি করবেন?"

"আমি একটি লুপ ব্যবহার করে সমস্ত উপাদানের মধ্যে চক্রাকারে ঘুরতে পারি এবং সেটের প্রতিটি বস্তুর সাথে বস্তুর তুলনা করতে পারি। যতক্ষণ না আমি একটি মিল খুঁজে পাই।"

"এবং যদি এটি সেখানে না থাকে? বস্তুটি সেখানে নেই তা খুঁজে বের করার জন্য আমরা এক মিলিয়ন তুলনা করব? এটি কি অনেক বেশি মনে হয় না?"

"হ্যাঁ, এমনকি আমি চিনতে পারি যে এটি অনেক বেশি তুলনা। অন্য উপায় আছে কি?"

"হ্যাঁ, আপনি এর জন্য হ্যাশকোড () ব্যবহার করতে পারেন।

হ্যাশকোড ( ) পদ্ধতি প্রতিটি বস্তুর জন্য একটি নির্দিষ্ট সংখ্যা প্রদান করে। একটি ক্লাসের বিকাশকারী ঠিক করে যে কোন সংখ্যাটি ফেরত দেওয়া হবে, ঠিক যেমন সে সমান পদ্ধতির জন্য করে।

"আসুন একটি উদাহরণ দেখি:"

"ভাবুন যে আপনার কাছে এক মিলিয়ন 10-সংখ্যার সংখ্যা আছে। তারপর, আপনি প্রতিটি নম্বরের হ্যাশকোডটিকে 100 দ্বারা ভাগ করার পরে অবশিষ্ট হিসাবে তৈরি করতে পারেন।"

এখানে একটি উদাহরণ:

সংখ্যা আমাদের হ্যাশকোড
1234567890 90
9876554321 21
9876554221 21
9886554121 21

"হ্যাঁ, এটা বোঝায়। এবং আমরা এই হ্যাশকোড দিয়ে কি করব?"

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

"এবং আমরা সমান কল করি শুধুমাত্র যদি তাদের হ্যাশকোড সমান হয়।"

"হ্যাঁ, এটি দ্রুত। কিন্তু আমাদের এখনও এক মিলিয়ন তুলনা করতে হবে। আমরা শুধু ছোট সংখ্যার তুলনা করছি, এবং আমাদের এখনও হ্যাশকোডের সাথে মিলে যাওয়া যেকোনো সংখ্যার জন্য সমান কল করতে হবে।"

"না, আপনি তুলনার অনেক ছোট সংখ্যা দিয়ে দূরে যেতে পারেন।"

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

"মনে করুন আপনি একজন ছাত্র এমন একজন বন্ধুকে খুঁজছেন যাকে আপনি দেখেই চিনতে পারেন এবং যাকে আমরা জানি ডর্ম 17-এ থাকে। তারপর আপনি শুধু বিশ্ববিদ্যালয়ের প্রতিটি ডর্মে যান এবং জিজ্ঞাসা করেন, 'এটি কি 17 ডর্ম?' যদি তা না হয়, তাহলে আপনি ডর্মের সবাইকে উপেক্ষা করে পরের দিকে চলে যান। উত্তর যদি 'হ্যাঁ' হয়, তাহলে আপনি আপনার বন্ধুর খোঁজে প্রতিটি ঘরের পাশ দিয়ে হাঁটতে শুরু করবেন।"

"এই উদাহরণে, ডর্ম নম্বর (17) হল হ্যাশকোড।"

"একজন বিকাশকারী যিনি একটি হ্যাশকোড ফাংশন প্রয়োগ করেন তাকে অবশ্যই নিম্নলিখিতগুলি জানতে হবে:"

ক)  দুটি ভিন্ন বস্তুর একই হ্যাশকোড থাকতে পারে  (বিভিন্ন মানুষ একই ডর্মে থাকতে পারে)

খ)  যে বস্তুগুলি একই  ( সমান পদ্ধতি অনুসারেতাদের অবশ্যই একই হ্যাশকোড থাকতে হবে। .

গ)  হ্যাশ কোড অবশ্যই বেছে নিতে হবে যাতে একই হ্যাশকোডের সাথে অনেকগুলি ভিন্ন বস্তু না থাকে।  যদি সেখানে থাকে, তাহলে হ্যাশকোডের সম্ভাব্য সুবিধাগুলি হারিয়ে যাবে (আপনি ডর্ম 17-এ যান এবং খুঁজে পাবেন যে অর্ধেক বিশ্ববিদ্যালয় সেখানে থাকে। বামার!)

"এবং এখন সবচেয়ে গুরুত্বপূর্ণ বিষয়। আপনি যদি সমান পদ্ধতিটি ওভাররাইড করেন, তাহলে আপনাকে অবশ্যই হ্যাশকোড () পদ্ধতিটিকে ওভাররাইড করতে হবে এবং উপরে বর্ণিত তিনটি নিয়ম মেনে চলতে হবে৷

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

"আমাদের ভগ্নাংশের উদাহরণে, যদি আমরা হ্যাশকোডকে লবের সমান করি, তাহলে ভগ্নাংশ 2/3 এবং 4/6 এর আলাদা আলাদা হ্যাশকোড থাকবে। ভগ্নাংশগুলি একই এবং সমান পদ্ধতি বলে যে তারা একই, কিন্তু তাদের হ্যাশকোডগুলি বলে তারা আলাদা। এবং যদি আমরা সমান ব্যবহার করে তুলনা করার আগে হ্যাশকোড ব্যবহার করে তুলনা করি, তাহলে আমরা উপসংহারে পৌঁছেছি যে বস্তুগুলি আলাদা এবং আমরা এটিকে সমান পদ্ধতিতেও পরিণত করতে পারি না।"

এখানে একটি উদাহরণ:

HashSet<Fraction>set = new HashSet<Fraction>();
set.add(new Fraction(2,3));System.out.println( set.contains(new Fraction(4,6)) );
যদি হ্যাশকোড()  পদ্ধতি ভগ্নাংশের সংখ্যা প্রদান করে, ফলাফলটি  মিথ্যা হবে ।
এবং "নতুন ভগ্নাংশ(4,6) " বস্তুটি সংগ্রহে পাওয়া যাবে না।

"তাহলে ভগ্নাংশের জন্য হ্যাশকোড প্রয়োগ করার সঠিক উপায় কি?"

"এখানে আপনাকে মনে রাখতে হবে যে সমতুল্য ভগ্নাংশের একই হ্যাশকোড থাকতে হবে।"

" সংস্করণ 1 : হ্যাশকোড পূর্ণসংখ্যা বিভাজনের ফলাফলের সমান।"

"7/5 এবং 6/5 এর জন্য, এটি 1 হবে।"

"4/5 এবং 3/5 এর জন্য, এটি 0 হবে।"

"কিন্তু এই বিকল্পটি ইচ্ছাকৃতভাবে 1 এর চেয়ে কম ভগ্নাংশের তুলনা করার জন্য খারাপভাবে উপযুক্ত। হ্যাশকোড (পূর্ণসংখ্যা বিভাগের ফলাফল) সর্বদা 0 হবে।"

" সংস্করণ 2 : হ্যাশকোড লব দ্বারা হর এর পূর্ণসংখ্যা বিভাজনের ফলাফলের সমান।"

"এই বিকল্পটি এমন দৃষ্টান্তগুলির জন্য উপযুক্ত যেখানে ভগ্নাংশটি 1-এর কম। যদি ভগ্নাংশটি 1-এর কম হয়, তবে এর বিপরীত 1-এর চেয়ে বেশি। এবং যদি আমরা সমস্ত ভগ্নাংশকে উল্টিয়ে দেই, তাহলে তুলনাগুলি কোনওভাবেই প্রভাবিত হয় না।"

"আমাদের চূড়ান্ত সংস্করণ উভয় সমাধানকে একত্রিত করে:"

public int hashCode()
{
return numerator/denominator + denominator/numerator;
}

আসুন এটি 2/3 এবং 4/6 ব্যবহার করে পরীক্ষা করি। তাদের অভিন্ন হ্যাশকোড থাকা উচিত:

ভগ্নাংশ 2/3 ভগ্নাংশ 4/6
লব হর 2 / 3 == 0 4 / 6 == 0
হর লব 3 / 2 == 1 6/4 == 1
লব / হর
+
হর / লব
0 + 1 == 1 0 + 1 == 1

"এখন এ পর্যন্তই."

"ধন্যবাদ, এলি। এটা সত্যিই আকর্ষণীয় ছিল।"