আসল উত্তর
কেন একটি Comparator
ইন্টারফেস কিন্তু না Hasher
এবং Equator
?
হ'ল, জোশ ব্লচের সৌজন্যে :
আসল জাভা এপিআইগুলি একটি ক্লোজড মার্কেট উইন্ডোটি পূরণ করতে একটি শক্ত সময়সীমার অধীনে খুব দ্রুত সম্পন্ন করা হয়েছিল। আসল জাভা দলটি অবিশ্বাস্য কাজ করেছে, তবে এপিআইয়ের সমস্তই নিখুঁত নয়।
সমস্যা অন্যান্য অনুরূপ বিষয়গুলি, যেমন মত জাভা ইতিহাসে একমাত্র মিথ্যা, .clone()
বনাম Cloneable
।
TL; ড
এটি মূলত historicalতিহাসিক কারণে; বর্তমান আচরণ / বিমূর্ততা জেডিকে ১.০ এ প্রবর্তিত হয়েছিল এবং এটি পরে ঠিক করা হয়নি কারণ পিছিয়ে কোডের সামঞ্জস্যতা বজায় রেখে এটি করা কার্যত অসম্ভব ছিল।
প্রথমে আসুন কয়েকটি সুপরিচিত জাভা তথ্য সংকলন করা যাক:
- জাভা, প্রথম থেকে আজ অবধি গর্বের সাথে পিছনের দিকে সামঞ্জস্যপূর্ণ, লেগ্যাসি এপিআইগুলি এখনও নতুন সংস্করণগুলিতে সমর্থিত হওয়া প্রয়োজন,
- যেমন, জেডিকে ১.০ এর সাথে প্রবর্তিত প্রায় প্রতিটি এবং প্রতিটি ভাষা নির্মাণ আজকাল বেঁচে ছিল,
Hashtable
, .hashCode()
এবং জেডিকে.equals()
১.০ এ প্রয়োগ করা হয়েছিল ( হ্যাশটেবল )
Comparable
/ Comparator
জেডিকে ১.২ ( তুলনীয় ) তে প্রবর্তিত হয়েছিল ,
এখন, এটি অনুসরণ:
- কার্যত অসম্ভব & রেট্রোফিট করার অজ্ঞান
.hashCode()
ও .equals()
স্বতন্ত্র ইন্টারফেসগুলি যখন এখনও মানুষ পর পিছন সামঞ্জস্য বজায় রাখার উপলব্ধি তাদের superobject নির্বাণ চেয়ে ভাল বিমূর্ত আছে, কারণ যেমন প্রতিটি এক 1.2 দ্বারা জাভা প্রোগ্রামার জানতেন যে যে Object
তাদের আছে, এবং তারা ছিল কম্পাইল কোড (জেভিএম) সামঞ্জস্যতাও শারীরিকভাবে সেখানে থাকার জন্য - এবং প্রতিটি Object
সাবক্লাসে একটি বাস্তব স্পেস ইন্টারফেস যুক্ত করা যা তাদের বাস্তবায়িত করে এই জগাখিচুড়ি সমান (sic!) Clonable
একের সমান করে দেবে ( ব্লচ আলোচনা করে কেন ক্লোনযোগ্য সফল হয়, উদাহরণস্বরূপ EJ 2 য় আলোচিত) এবং এসও সহ আরও অনেক স্থান),
- ভবিষ্যতের প্রজন্মের ডাব্লুটিএফ-এর একটি অবিচ্ছিন্ন উত্স পাওয়ার জন্য তারা কেবল তাদের সেখানে রেখে গেছে।
এখন, আপনি জিজ্ঞাসা করতে পারেন " Hashtable
এই সমস্ত কি আছে"?
উত্তরটি হ'ল: hashCode()
/equals()
1995 এবং ১৯৯৯ / ১৯৯6 সালে মূল জাভা বিকাশকারীদের পক্ষে ভাষা চুক্তি এবং তেমন ভাল না ভাষা দক্ষতার দক্ষতা।
জাভা 1.0 ভাষা প্রতিবেদনের উদ্ধৃতি , তারিখ 1996 - 4.3.2 ক্লাস Object
, পৃষ্ঠা 45:
পদ্ধতিগুলি equals
এবং হ্যাশ টেবিলের hashCode
সুবিধার জন্য যেমন ঘোষণা করা হয় java.util.Hashtable
(21.7.7)। সমান পদ্ধতিটি অবজেক্টের সাম্যের ধারণাটি সংজ্ঞায়িত করে, যা মানের উপর ভিত্তি করে, রেফারেন্স, তুলনা করে না।
(নোট ঠিক এই বিবৃতি হয়েছে পরিবর্তিত : পরে সংস্করণে বলতে উদ্ধৃতি The method hashCode is very useful, together with the method equals, in hashtables such as java.util.HashMap.
, এটা অসম্ভব সরাসরি করতে উপার্জন Hashtable
- hashCode
- equals
ঐতিহাসিক JLS পড়া ছাড়া সংযোগ!)
জাভা দল সিদ্ধান্ত নিয়েছে যে তারা একটি ভাল অভিধান-স্টাইলের সংগ্রহ চায়, এবং তারা তৈরি করেছে Hashtable
(এখনও অবধি ভাল ধারণা) তবে তারা চেয়েছিল যে প্রোগ্রামার এটি যতটা সম্ভব কম কোড / শেখার বক্ররেখ ব্যবহার করতে সক্ষম হবে (ওফ! সমস্যা আগত!) - এবং, যেহেতু এখনো [এটা JDK 1.0 সব পরে] কোনো জেনেরিক্স হয়েছিলেন যে অর্থ হবে যে হয় যে Object
পুরা Hashtable
স্পষ্টভাবে কিছু ইন্টারফেস বাস্তবায়ন করতে হবে (এবং ইন্টারফেস তখন শুধু তাদের শুরু মধ্যে আছেন তাই ... কোনও Comparable
এমনকি এখনো!) , এই একটি প্রতিবন্ধক উপার্জন অনেকের জন্য এটি ব্যবহার করতে - বা Object
করতে হবে পরোক্ষভাবে কিছু হ্যাশ পদ্ধতি বাস্তবায়ন।
স্পষ্টতই, তারা উপরোক্ত কারণগুলির জন্য সমাধান 2 নিয়ে গেল। হ্যাঁ, এখন আমরা জানি তারা ভুল ছিল। ... হ্যান্ডসাইটে স্মার্ট হওয়া সহজ। মৃদুহাস্য
এখন, hashCode()
প্রয়োজন যে প্রতিটি বস্তুর এটির একটি পৃথক equals()
পদ্ধতি থাকতে হবে - সুতরাং এটি স্পষ্টভাবে স্পষ্ট equals()
ছিল যে এটিও রাখা উচিত Object
।
যেহেতু ডিফল্ট বৈধ সেই পদ্ধতি বাস্তবায়নের a
& b
Object
(উপার্জন গুলি মূলত অপ্রয়োজনীয় হচ্ছে বেহুদা হয় a.equals(b)
সমান করতে a==b
এবং a.hashCode() == b.hashCode()
মোটামুটিভাবে সমান করতে a==b
, এছাড়াও , যদি না hashCode
এবং / অথবা equals
ওভাররাইড করা হয়, অথবা আপনি জিসি কয়েক হাজার Object
আপনার আবেদনের জীবনচক্র সময় গুলি 1 ) , এটি নিরাপদ যে এগুলিকে মূলত ব্যাকআপ ব্যবস্থা এবং ব্যবহারের সুবিধার জন্য সরবরাহ করা হয়েছিল তা বলা নিরাপদ। ঠিক একইভাবে আমরা সুপরিচিত সত্যের কাছে পৌঁছে যাই যে উভয়কেই সর্বদা ওভাররাইড করে .equals()
এবং .hashCode()
আপনি যদি বস্তুগুলির সাথে তুলনা করতে বা হ্যাশ-স্টোর করার চেষ্টা করেন। অন্যটি ছাড়াই কেবল একটির ওভাররাইড করা আপনার কোডটি স্ক্রু করার একটি ভাল উপায় (দুষ্টু ফলাফলের তুলনায় বা অত্যধিক উচ্চ বালতির সংঘর্ষের মানগুলি দ্বারা) - এবং এটির চারপাশে আপনার মাথা পাওয়াটি ধ্রুবক বিভ্রান্তির কারণ এবং নতুনদের জন্য ত্রুটি (অনুসন্ধানের জন্য এসও অনুসন্ধান করুন) এটি নিজের জন্য) এবং আরও পাকা ব্যক্তিদের কাছে ধ্রুবক উপদ্রব।
এছাড়াও, মনে রাখবেন যে যদিও ভাল উপায় বিট সমান & একটি হ্যাশকোড সঙ্গে সি # পুলিশ এরিক Lippert নিজে যে তারা C # এর প্রায় একই ভুল করেনি সূর্য জাভা বছর করেছিল সি # 'গুলি শুরু করার আগে :
তবে কেন এমন হওয়া উচিত যে প্রতিটি বস্তুর একটি হ্যাশ টেবিলের মধ্যে প্রবেশের জন্য নিজেকে হ্যাশ করতে সক্ষম হওয়া উচিত? প্রতিটি অবজেক্টটি সক্ষম হতে সক্ষম হওয়া একটি বিজোড় জিনিসের মতো মনে হয়। আমি মনে করি আমরা যদি আজ থেকে স্ক্র্যাচ থেকে টাইপ সিস্টেমটিকে নতুনভাবে ডিজাইন করছিলাম, হ্যাশিং অন্যরকমভাবে করা হতে পারে, সম্ভবত কোনও IHashable
ইন্টারফেস দিয়ে। কিন্তু যখন সিএলআর টাইপ সিস্টেমটি তৈরি করা হয়েছিল তখন কোনও জেনেরিক প্রকার ছিল না এবং তাই কোনও সাধারণ-উদ্দেশ্য হ্যাশ টেবিলটি কোনও বস্তু সঞ্চয় করতে সক্ষম হওয়ার প্রয়োজন ছিল।
1 অবশ্যই, Object#hashCode
এখনও সংঘর্ষ করতে পারে, তবে এটি করতে কিছুটা প্রচেষ্টা দরকার, দেখুন: http://bugs.java.com/bugdatedia/view_bug.do?bug_id=6809470 এবং বিশদ সম্পর্কিত লিঙ্কযুক্ত বাগ রিপোর্ট; /programming/1381060/hashcode-uniqueness/1381114#1381114 এই বিষয়টিকে আরও গভীরতার সাথে কভার করে।
Person
প্রত্যাশিতequals
এবংhashCode
আচরণ বাস্তবায়নের জন্য আপনি সর্বদা মোড়কের জিনিসগুলি প্রবর্তন করতে পারেন । আপনি তখন একটি ছিলHashMap<PersonWrapper, V>
। এটি একটি উদাহরণ যেখানে খাঁটি-ওওপি পদ্ধতির মার্জিত নয়: কোনও বস্তুর প্রতিটি ক্রিয়াকলাপই সেই বস্তুর একটি পদ্ধতি হিসাবে বোধ করে না। জাভার পুরোObject
টাইপ বিভিন্ন দায়িত্ব সংমিশ্রণ হয় - শুধুমাত্রgetClass
,finalize
এবংtoString
পদ্ধতি আজকের সর্বোত্তম কার্যাভ্যাস দ্বারা দূরবর্তী সমর্থনীয় বলে মনে হচ্ছে।