1. জাভাতে বস্তুর তুলনা করা
জাভাতে, বস্তুকে রেফারেন্স এবং মান দ্বারা উভয়ই তুলনা করা যেতে পারে।
রেফারেন্স তুলনা
যদি দুটি ভেরিয়েবল একই বস্তুকে মেমরিতে নির্দেশ করে, তাহলে এই ভেরিয়েবলে সংরক্ষিত রেফারেন্স সমান। যদি আপনি সমতা অপারেটর ( ==
) ব্যবহার করে এই ভেরিয়েবলগুলির তুলনা করেন, তাহলে আপনি সত্য পাবেন, এবং সেই ফলাফলটি বোঝা যায়। এখানে সবকিছু সহজ.
কোড | কনসোল আউটপুট |
---|---|
|
|
মান দ্বারা তুলনা
কিন্তু আপনি প্রায়শই এমন পরিস্থিতির সম্মুখীন হতে পারেন যেখানে দুটি ভেরিয়েবল অভিন্ন দুটি স্বতন্ত্র বস্তুকে নির্দেশ করে। উদাহরণস্বরূপ, দুটি ভিন্ন স্ট্রিং অবজেক্ট যা একই পাঠ্য ধারণ করে।
বিভিন্ন বস্তু অভিন্ন কিনা তা নির্ধারণ করতে, equals()
পদ্ধতিটি ব্যবহার করুন। উদাহরণ স্বরূপ:
কোড | কনসোল আউটপুট |
---|---|
|
|
পদ্ধতিটি equals
ক্লাসের মধ্যে সীমাবদ্ধ নয় String
। প্রতিটি ক্লাস এটি আছে.
এমনকি ক্লাস যেগুলো আপনি নিজে থেকে লেখেন, এবং এখানে কেন।
2. Object
ক্লাস
জাভাতে সমস্ত ক্লাস ক্লাসের উত্তরাধিকারী Object
। জাভা এর নির্মাতারা এই পদ্ধতির সাথে এসেছেন।
এবং যদি একটি ক্লাস Object
ক্লাসের উত্তরাধিকারী হয়, তবে এটি ক্লাসের সমস্ত পদ্ধতি লাভ করে Object
। এবং এটি উত্তরাধিকারের একটি প্রধান পরিণতি।
অন্য কথায়, প্রতিটি ক্লাসের ক্লাসের পদ্ধতি রয়েছে Object
, এমনকি তাদের কোডে সেগুলি উল্লেখ না থাকলেও।
এই উত্তরাধিকারসূত্রে প্রাপ্ত পদ্ধতিগুলি বস্তুর তুলনা সম্পর্কিত পদ্ধতিগুলি অন্তর্ভুক্ত করে। এই equals()
এবং hashCode()
পদ্ধতি.
কোড | বাস্তবে, আমাদের যা থাকবে তা এখানে: |
---|---|
|
|
উপরের উদাহরণে, আমরা Person
নাম এবং বয়সের পরামিতি সহ একটি সাধারণ ক্লাস তৈরি করেছি, কিন্তু একটি একক পদ্ধতি নয়। কিন্তু যেহেতু সমস্ত ক্লাস Object
ক্লাসের উত্তরাধিকারী, Person
ক্লাসের স্বয়ংক্রিয়ভাবে দুটি পদ্ধতি রয়েছে:
পদ্ধতি | বর্ণনা |
---|---|
|
বর্তমান বস্তু এবং পাস করা বস্তুর তুলনা করে |
|
বর্তমান বস্তুর হ্যাশকোড প্রদান করে |
দেখা যাচ্ছে যে একেবারে প্রতিটি বস্তুর equals
পদ্ধতি রয়েছে এবং বিভিন্ন ধরণের বস্তু একে অপরের সাথে তুলনা করা যেতে পারে। এই ধরনের কোড কম্পাইল করবে এবং পুরোপুরি কাজ করবে।
কোড | কনসোল আউটপুট |
---|---|
|
|
|
|
3. equals()
পদ্ধতি
পদ্ধতি equals()
, ক্লাস থেকে উত্তরাধিকারসূত্রে প্রাপ্ত Object
, পাস করা বস্তুর সাথে বর্তমান অবজেক্টের তুলনা করার জন্য সবচেয়ে সহজ অ্যালগরিদম প্রয়োগ করে: এটি শুধুমাত্র বস্তুর রেফারেন্সের সাথে তুলনা করে।
আপনি একই ফলাফল পাবেন যদি আপনি পদ্ধতিটি Person
কল করার পরিবর্তে ভেরিয়েবলের তুলনা করেন equals()
। উদাহরণ:
কোড | কনসোল আউটপুট |
---|---|
|
|
যখন equals
পদ্ধতিটি কল করা হয় a
, তখন এটি কেবলমাত্র ভেরিয়েবলে সংরক্ষিত রেফারেন্সের a
সাথে ভেরিয়েবলে সংরক্ষিত রেফারেন্সের সাথে তুলনা করে b
।
যাইহোক, তুলনা String
ক্লাসের জন্য ভিন্নভাবে কাজ করে। কেন?
কারণ যারা String
ক্লাস তৈরি করেছে তারা তাদের নিজস্ব পদ্ধতির বাস্তবায়ন লিখেছে equals()
।
equals()
পদ্ধতির বাস্তবায়ন
এখন ক্লাসে সমান পদ্ধতির নিজস্ব বাস্তবায়ন লিখি Person
। আমরা 4টি প্রধান ক্ষেত্রে বিবেচনা করব।
equals
পদ্ধতিটিকে ওভাররাইড করে না কেন, এটি সর্বদা একটি Object
বস্তুকে যুক্তি হিসাবে নেয়
দৃশ্যকল্প 1equals
: যে বস্তুর উপর পদ্ধতিটি বলা হয় একই বস্তুটিও equals
পদ্ধতিতে পাস করা হয়। যদি বর্তমান অবজেক্ট এবং পাস করা বস্তুর রেফারেন্স সমান হয়, তবে পদ্ধতিটি অবশ্যই ফেরত দিতে হবে true
। একটি বস্তু নিজেই সমান।
কোডে এটি এই মত দেখাবে:
কোড | বর্ণনা |
---|---|
|
রেফারেন্স তুলনা করুন |
দৃশ্যকল্প 2 : null
পদ্ধতিতে পাস করা হয়েছে equals
— আমাদের তুলনা করার কিছুই নেই। যে বস্তুটির উপর equals
পদ্ধতিটি বলা হয়েছে সেটি অবশ্যই শূন্য নয়, তাই আমাদের false
এই ক্ষেত্রে ফিরে আসতে হবে।
কোডে এটি এই মত দেখাবে:
কোড | বর্ণনা |
---|---|
|
রেফারেন্স তুলনা পাস করা বস্তু কি null ? |
দৃশ্যকল্প 3 : একটি বস্তুর একটি রেফারেন্স যা একটি নয় Person
পদ্ধতিতে পাস করা হয় equals
। বস্তুটি কি Person
অ-বস্তুর সমান Person
? এটি ক্লাসের বিকাশকারীর পক্ষে Person
সিদ্ধান্ত নেওয়ার জন্য একটি প্রশ্ন যা সে চায়।
কিন্তু সাধারনত অবজেক্টকে সমান হিসাবে বিবেচনা করার জন্য একই শ্রেণীর হতে হবে। অতএব, যদি ক্লাসের একটি অবজেক্ট ছাড়া অন্য কিছু Person
আমাদের সমান পদ্ধতিতে পাস করা হয়, তাহলে আমরা সর্বদা ফিরে আসব false
। আপনি কিভাবে একটি বস্তুর ধরন পরীক্ষা করতে পারেন? এটা ঠিক — instanceof
অপারেটর ব্যবহার করে.
আমাদের নতুন কোড দেখতে কেমন তা এখানে:
কোড | বর্ণনা |
---|---|
|
রেফারেন্স তুলনা পাস করা বস্তু কি null ? পাস করা বস্তু না হলে a Person |
Person
4. দুটি বস্তুর তুলনা
আমরা কি শেষ করেছিলাম? যদি আমরা পদ্ধতির শেষে পৌঁছে থাকি, তাহলে আমাদের কাছে একটি Person
বস্তুর রেফারেন্স আছে যা নয় null
। তাই আমরা এটিকে a এ রূপান্তর করি Person
এবং উভয় বস্তুর প্রাসঙ্গিক অভ্যন্তরীণ ডেটা তুলনা করি। এবং এটি আমাদের চতুর্থ দৃশ্যকল্প ।
কোড | বর্ণনা |
---|---|
|
রেফারেন্স তুলনা পাস করা বস্তু কি null ? যদি পাস করা বস্তুটি Person টাইপকাস্টিং না হয় |
Person
এবং কিভাবে আপনি দুটি বস্তুর তুলনা করবেন ? name
একই নাম ( ) এবং বয়স ( age
) থাকলে তারা সমান । চূড়ান্ত কোড এই মত দেখাবে:
কোড | বর্ণনা |
---|---|
|
রেফারেন্স তুলনা পাস করা বস্তু কি null ? যদি পাস করা বস্তুটি Person টাইপকাস্টিং না হয় |
কিন্তু এখানেই শেষ নয়.
প্রথমত, নামের ক্ষেত্রটি হল একটি , তাই আপনাকে পদ্ধতিটি String
কল করে নামের ক্ষেত্রটির তুলনা করতে হবে ।equals
this.name.equals(person.name)
দ্বিতীয়ত, name
ক্ষেত্রটি হতে পারে null
: সেই ক্ষেত্রে, আপনি equals
এটিতে কল করতে পারবেন না। আপনার জন্য একটি অতিরিক্ত চেক প্রয়োজন null
:
this.name != null && this.name.equals(person.name)
এটি বলেছে, যদি নামের ক্ষেত্রটি null
উভয় Person
বস্তুতে থাকে, তবে নামগুলি এখনও সমান।
চতুর্থ দৃশ্যের জন্য কোড এই মত দেখতে হতে পারে:
|
বয়স সমান না হলে, অবিলম্বে return false যদি this.name সমান হয় , পদ্ধতি null ব্যবহার করে তুলনা করার কোন মানে নেই । equals এখানে হয় দ্বিতীয় name ক্ষেত্রটি সমান null , বা এটি নয়। পদ্ধতি ব্যবহার করে দুটি নামের ক্ষেত্রের তুলনা করুন equals । |
5. hashCode()
পদ্ধতি
পদ্ধতিটি ছাড়াও equals
, যা উভয় বস্তুর সমস্ত ক্ষেত্রের বিশদ তুলনা করার উদ্দেশ্যে করা হয়েছে, আরেকটি পদ্ধতি রয়েছে যা একটি অস্পষ্ট কিন্তু খুব দ্রুত তুলনার জন্য ব্যবহার করা যেতে পারে: hashCode()
.
কল্পনা করুন আপনি বর্ণানুক্রমিকভাবে হাজার হাজার শব্দের একটি তালিকা বাছাই করছেন, এবং আপনাকে বারবার জোড়া শব্দের তুলনা করতে হবে। এবং শব্দগুলি দীর্ঘ, প্রচুর অক্ষর সমন্বিত। সাধারণভাবে বলতে গেলে, এই ধরনের তুলনা খুব দীর্ঘ সময় লাগবে।
তবে এটি ত্বরান্বিত করা যেতে পারে। ধরুন আমাদের কাছে বিভিন্ন অক্ষর দিয়ে শুরু হওয়া শব্দ আছে - এটি অবিলম্বে স্পষ্ট যে তারা আলাদা। কিন্তু যদি তারা একই অক্ষর দিয়ে শুরু হয়, তাহলে আমরা এখনও বলতে পারি না যে ফলাফল কী হবে: শব্দগুলি সমান বা ভিন্ন হতে পারে।
পদ্ধতিটি hashCode()
একই নীতি ব্যবহার করে কাজ করে। আপনি যদি এটিকে একটি বস্তুতে কল করেন তবে এটি কিছু সংখ্যা ফেরত দেয় - একটি শব্দের প্রথম অক্ষরের অনুরূপ। এই সংখ্যার নিম্নলিখিত বৈশিষ্ট্য রয়েছে:
- অভিন্ন বস্তুর সবসময় একই হ্যাশকোড থাকে
- বিভিন্ন বস্তুর একই হ্যাশকোড থাকতে পারে, বা তাদের হ্যাশকোড ভিন্ন হতে পারে
- যদি বস্তুর বিভিন্ন হ্যাশকোড থাকে, তাহলে বস্তুগুলি অবশ্যই ভিন্ন
এটি আরও স্পষ্ট করার জন্য, আসুন এই বৈশিষ্ট্যগুলিকে শব্দের পরিপ্রেক্ষিতে রিফ্রেম করি:
- অভিন্ন শব্দের সর্বদা একই প্রথম অক্ষর থাকে।
- বিভিন্ন শব্দের একই প্রথম অক্ষর থাকতে পারে বা তাদের প্রথম অক্ষর ভিন্ন হতে পারে
- যদি শব্দের প্রথম অক্ষর আলাদা থাকে, তবে শব্দগুলি অবশ্যই আলাদা
শেষ সম্পত্তি বস্তুর তুলনা ত্বরান্বিত করতে ব্যবহৃত হয়:
প্রথমত, দুটি বস্তুর হ্যাশকোড গণনা করা হয়। যদি এই হ্যাশকোডগুলি আলাদা হয়, তবে বস্তুগুলি অবশ্যই আলাদা, এবং তাদের তুলনা করার দরকার নেই।
কিন্তু যদি হ্যাশকোড একই হয়, তাহলে আমাদের এখনও সমান পদ্ধতি ব্যবহার করে বস্তুর তুলনা করতে হবে।
6. কোডে চুক্তি
উপরে বর্ণিত আচরণ অবশ্যই জাভাতে সমস্ত শ্রেণীর দ্বারা প্রয়োগ করা উচিত। সংকলনের সময়, বস্তুগুলি সঠিকভাবে তুলনা করা হয়েছে কিনা তা পরীক্ষা করার কোন উপায় নেই।
জাভা প্রোগ্রামারদের একটি সার্বজনীন চুক্তি রয়েছে যে তারা যদি সমান() পদ্ধতির নিজস্ব বাস্তবায়ন লিখে এবং এর ফলে স্ট্যান্ডার্ড ইমপ্লিমেন্টেশন (ক্লাসে Object
) ওভাররাইড করে তবে তাদের অবশ্যই পদ্ধতির নিজস্ব বাস্তবায়ন hashCode()
এমনভাবে লিখতে হবে যাতে পূর্বোক্ত নিয়মগুলি সন্তুষ্ট.
এই ব্যবস্থাকে চুক্তি বলা হয় ।
আপনি যদি আপনার ক্লাসে শুধুমাত্র equals()
বা শুধুমাত্র hashCode()
পদ্ধতিটি প্রয়োগ করেন, তাহলে আপনি চুক্তির চরম লঙ্ঘন করছেন (আপনি চুক্তি ভঙ্গ করেছেন)। এটা করবেন না।
যদি অন্য প্রোগ্রামাররা আপনার কোড ব্যবহার করে তবে এটি সঠিকভাবে কাজ নাও করতে পারে। আরো কি, আপনি কোড ব্যবহার করবেন যা উপরোক্ত চুক্তির আনুগত্যের উপর নির্ভর করে।
একটি উপাদান অনুসন্ধান করার সময়, সমস্ত জাভা সংগ্রহ প্রথমে বস্তুর হ্যাশকোড তুলনা করে, এবং শুধুমাত্র তারপর equals
পদ্ধতি ব্যবহার করে একটি তুলনা সম্পাদন করে।
এর মানে হল যে আপনি যদি আপনার নিজের ক্লাসকে একটি equals
পদ্ধতি দেন কিন্তু আপনি নিজের hashCode()
পদ্ধতিটি না লিখেন বা আপনি এটি ভুলভাবে প্রয়োগ করেন, তাহলে সংগ্রহগুলি আপনার বস্তুর সাথে সঠিকভাবে কাজ নাও করতে পারে।
উদাহরণস্বরূপ, আপনি একটি তালিকায় একটি বস্তু যোগ করতে পারেন এবং তারপর contains()
পদ্ধতিটি ব্যবহার করে এটি অনুসন্ধান করতে পারেন, কিন্তু সংগ্রহটি আপনার বস্তুটি খুঁজে নাও পেতে পারে।
GO TO FULL VERSION