"অন / অফ টপিক" এর ধূসর অঞ্চলে প্রবেশ করা, তবে অস্কার রেসের বিষয়ে বিভ্রান্তি দূর করতে প্রয়োজনীয় পরামর্শ দেওয়া হয়েছে যে আরও হ্যাশের সংঘর্ষ একটি ভাল জিনিস কারণ এটি হ্যাশম্যাপে উপাদানগুলির সংখ্যা হ্রাস করে। অস্কার যা বলছে তা আমি ভুল বুঝতে পারি, তবে আমি কেবল একটাই বলে মনে করি না: কেডিগ্রিগরি, ডেল্ফুয়েগো, ন্যাশ ০ এবং আমি সকলেই একই (ভুল) বোঝাপড়া ভাগ করে নিচ্ছি।
যদি আমি বুঝতে পারি যে একই হ্যাশকোড সহ অস্কার একই শ্রেণীর বিষয়ে কী বলছে, তবে তিনি প্রস্তাব দিচ্ছেন যে কোনও হ্যাশকোডযুক্ত শ্রেণীর কেবলমাত্র একটি উদাহরণ হ্যাশম্যাপে প্রবেশ করাবে। উদাহরণস্বরূপ, যদি আমার 1 এর একটি হ্যাশকোড সহ সামার ক্লাসের উদাহরণ থাকে এবং 1 এর হ্যাশকোড সহ সামারক্লাসের দ্বিতীয় উদাহরণ থাকে তবে সামার ক্লাসের কেবল একটি উদাহরণ সন্নিবেশ করা হয়।
Http://pastebin.com/f20af40b9 তে জাভা পেস্টবিন উদাহরণটি অস্কারের প্রস্তাবের উপরোক্ত সঠিকভাবে সংক্ষিপ্ত আকারে ইঙ্গিত দেয় বলে মনে হচ্ছে।
কোনও বোঝাপড়া বা ভুল বোঝাবুঝি না করেই, যা হয় তা একই শ্রেণীর বিভিন্ন উদাহরণ হ্যাশম্যাপে একবারে sertedোকানো হয় না যদি তাদের একই হ্যাশকোড থাকে - যতক্ষণ না এটি নির্ধারিত হয় না কীগুলি সমান কিনা। হ্যাশকোড চুক্তির জন্য সমান অবজেক্টগুলির একই হ্যাশকোড থাকা দরকার; তবে এটির জন্য অসম বস্তুগুলির বিভিন্ন হ্যাশকোড থাকা প্রয়োজন হয় না (যদিও এটি অন্যান্য কারণে পছন্দসই হতে পারে) [1]।
পেস্টবিন.com/f20af40b9 উদাহরণ (যা অস্কার কমপক্ষে দু'বার বোঝায়) অনুসরণ করে তবে প্রিন্টলাইনগুলির পরিবর্তে JUnit উক্তির ব্যবহারের জন্য সামান্য পরিবর্তিত। এই উদাহরণটি সেই প্রস্তাবটিকে সমর্থন করতে ব্যবহৃত হয় যে একই হ্যাশকোড সংঘর্ষের কারণ হয় এবং যখন ক্লাসগুলি একই হয় তখন কেবল একটি প্রবেশিকা তৈরি করা হয় (যেমন, এই নির্দিষ্ট ক্ষেত্রে কেবল একটি স্ট্রিং):
@Test
public void shouldOverwriteWhenEqualAndHashcodeSame() {
String s = new String("ese");
String ese = new String("ese");
// same hash right?
assertEquals(s.hashCode(), ese.hashCode());
// same class
assertEquals(s.getClass(), ese.getClass());
// AND equal
assertTrue(s.equals(ese));
Map map = new HashMap();
map.put(s, 1);
map.put(ese, 2);
SomeClass some = new SomeClass();
// still same hash right?
assertEquals(s.hashCode(), ese.hashCode());
assertEquals(s.hashCode(), some.hashCode());
map.put(some, 3);
// what would we get?
assertEquals(2, map.size());
assertEquals(2, map.get("ese"));
assertEquals(3, map.get(some));
assertTrue(s.equals(ese) && s.equals("ese"));
}
class SomeClass {
public int hashCode() {
return 100727;
}
}
তবে হ্যাশকোড সম্পূর্ণ গল্প নয়। পেস্টবিন উদাহরণ যা উপেক্ষা করে তা হ'ল উভয় s
এবং ese
সমান: এগুলি উভয়ই "ese" স্ট্রিং। সুতরাং, ঢোকাতে বা বের ব্যবহার মানচিত্র বিষয়বস্তু পেয়ে s
বা ese
বা "ese"
কী-এর মত সব সমতুল্য কারণ হয় s.equals(ese) && s.equals("ese")
।
দ্বিতীয় পরীক্ষাটি প্রমাণ করে যে এটি একই ফলশ্রুতিতে ভুল হয়েছে যে একই ক্লাসে অভিন্ন হ্যাশকোডগুলি কারণ -> টেস্টে ডাকা s -> 1
হয় ese -> 2
যখন মূল -> মানটি ওভাররাইট করা হয় map.put(ese, 2)
। দুটি পরীক্ষায় s
এবং ese
এখনও একই হ্যাশকোড রয়েছে (যাচাই করা হয়েছে assertEquals(s.hashCode(), ese.hashCode());
) এবং তারা একই শ্রেণি। যাইহোক, s
এবং ese
হয় MyString
দৃষ্টান্ত এই পরীক্ষা না জাভা String
: এই পরীক্ষা সমান হওয়ার জন্য প্রাসঙ্গিক শুধু পার্থক্য সাথে - দৃষ্টান্ত String s equals String ese
উপরে পরীক্ষা এক, যেহেতু MyStrings s does not equal MyString ese
পরীক্ষা দুই:
@Test
public void shouldInsertWhenNotEqualAndHashcodeSame() {
MyString s = new MyString("ese");
MyString ese = new MyString("ese");
// same hash right?
assertEquals(s.hashCode(), ese.hashCode());
// same class
assertEquals(s.getClass(), ese.getClass());
// BUT not equal
assertFalse(s.equals(ese));
Map map = new HashMap();
map.put(s, 1);
map.put(ese, 2);
SomeClass some = new SomeClass();
// still same hash right?
assertEquals(s.hashCode(), ese.hashCode());
assertEquals(s.hashCode(), some.hashCode());
map.put(some, 3);
// what would we get?
assertEquals(3, map.size());
assertEquals(1, map.get(s));
assertEquals(2, map.get(ese));
assertEquals(3, map.get(some));
}
/**
* NOTE: equals is not overridden so the default implementation is used
* which means objects are only equal if they're the same instance, whereas
* the actual Java String class compares the value of its contents.
*/
class MyString {
String i;
MyString(String i) {
this.i = i;
}
@Override
public int hashCode() {
return 100727;
}
}
পরবর্তী মন্তব্যের ভিত্তিতে অস্কার মনে হয় যে তিনি যা বলেছিলেন তার বিপরীতে আছে এবং সমতার গুরুত্ব স্বীকার করে। যাইহোক, এটি এখনও একই ধারণাটি সমান বলে মনে হয়, "একই শ্রেণি" নয়, অস্পষ্ট (জোর দেওয়া খনি):
"আসলেই নয়। হ্যাশটি একই হলে তালিকাটি তৈরি করা হয় তবে কীটি আলাদা instance উদাহরণস্বরূপ যদি কোনও স্ট্রিং হ্যাশকোড 2345 দেয় এবং পূর্ণসংখ্যা একই হ্যাশকোডকে 2345 দেয় তবে স্ট্রিংয়ের কারণে পূর্ণসংখ্যা তালিকায় প্রবেশ করা হয়। সমান (পূর্ণসংখ্যা) মিথ্যা। কিন্তু যদি আপনি একই ক্লাসে আছে (বা অন্তত .equals আয় সত্য কোণে) তারপর একই এন্ট্রি ব্যবহার করা হয়। উদাহরণস্বরূপ নতুন স্ট্রিং ( "এক") এবং `নতুন স্ট্রিং (" এক ") হিসেবে ব্যবহার করা জন্য কীগুলি, একই প্রবেশিকাটি ব্যবহার করবে ually বাস্তবে এটি হ্যাশম্যাপের পুরো পয়েন্টটি প্রথম স্থানে! নিজের জন্য দেখুন: পেস্টবিন.com/f20af40b9 - অস্কার রেইস "
পূর্ববর্তী মন্তব্যগুলির বিরুদ্ধে বনাম যা সমতুল্য কোনও উল্লেখ ছাড়াই অভিন্ন শ্রেণি এবং একই হ্যাশকোডের গুরুত্বকে সুস্পষ্টভাবে সম্বোধন করে:
"@ ডেল্ভেয়েগো: নিজের জন্য দেখুন: পেস্টবিন.com/f20af40b9 সুতরাং, এই প্রশ্নে একই শ্রেণিটি ব্যবহার করা হচ্ছে (এক মিনিট অপেক্ষা করুন, একই শ্রেণিটি সঠিকভাবে ব্যবহৃত হচ্ছে?) যা বোঝায় যে একই হ্যাশ একই প্রবেশিকা ব্যবহার করা হলে? ব্যবহৃত হয় এবং প্রবেশের "তালিকা" নেই not অস্কার রেইস "
অথবা
"আসলে এটি পারফরম্যান্সকে বাড়িয়ে দেবে। হ্যাশটেবল এক-এ আরও বেশি সংঘর্ষ যেমন কম এন্ট্রি করাতে হবে। হ্যাশ (যা ভাল দেখায়) বা হ্যাশ টেবিল (যা দুর্দান্ত কাজ করে না) আমি বাজি ধরে নিই এটি অবজেক্টে রয়েছে সৃষ্টি যেখানে কর্মক্ষমতা হ্রাস পাচ্ছে - অস্কার রেইস "
অথবা
"@ কেডিগ্রিগরি: হ্যাঁ, তবে কেবল একই ক্লাসের জন্য (যা ক্ষেত্রে) বিভিন্ন শ্রেণীর সাথে সংঘর্ষ ঘটে তবে একই প্রবেশিকা ব্যবহার করা হয়। অস্কার রেইস"
আবার অস্কার আসলে কী বলতে চাইছিল তা আমি ভুল বুঝতে পারি। তবে, তার আসল মন্তব্যগুলি যথেষ্ট বিভ্রান্তির কারণ করেছে যে কিছু স্পষ্ট পরীক্ষা দিয়ে সবকিছু পরিষ্কার করা বুদ্ধিমান বলে মনে হচ্ছে যাতে কোনও স্থির সন্দেহ নেই।
[1] - কার্যকর জাভা থেকে , জোশুয়া ব্লচের দ্বিতীয় সংস্করণ :
যখনই কোনও অ্যাপ্লিকেশন কার্যকর করার সময় এটি একই বস্তুটির উপরে একাধিকবার আহ্বান জানানো হয়, হ্যাশকোড পদ্ধতিটি ধারাবাহিকভাবে একই পূর্ণসংখ্যাকে ফেরত পাঠাতে হবে, যদি না বস্তুটির সমমানের তুলনায় ব্যবহৃত কোনও তথ্য সংশোধিত না হয়। এই পূর্ণসংখ্যার কোনও প্রয়োগের একটি প্রয়োগ থেকে একই অ্যাপ্লিকেশনটির অন্য প্রয়োগে সামঞ্জস্য থাকা উচিত নয়।
যদি দুটি বস্তু সমান s (ওবজ ect) পদ্ধতি অনুসারে সমান হয়, তবে দুটি বস্তুর প্রত্যেকটিতে হ্যাশকোড পদ্ধতিতে কল করার জন্য একই পূর্ণসংখ্যার ফলাফল উত্পন্ন করতে হবে।
এটি প্রয়োজন হয় না যে যদি দুটি বস্তু সমান (অবজেক্ট) পদ্ধতি অনুসারে অসম হয়, তবে দুটি বস্তুর প্রত্যেকটিতে হ্যাশকোড পদ্ধতি কল করার ক্ষেত্রে পৃথক পূর্ণসংখ্যার ফলাফল অবশ্যই পাওয়া উচিত। তবে প্রোগ্রামারকে সচেতন হওয়া উচিত যে অসম বস্তুর জন্য স্বতন্ত্র পূর্ণসংখ্যার ফলাফলগুলি হ্যাশ টেবিলগুলির কার্যকারিতা উন্নত করতে পারে।