نعلم جميعًا أن لغة جافا موجهة تمامًا للكائنات. في Java ، يتم توريث جميع الكائنات من فئة الكائن.
تقارن طريقة متساوية العناوين المشار إليها من خلال مراجع كائنين. HashCode هي طريقة محلية ، والتي تُرجع قيمة عنوان الكائن. هناك طريقتان في فئة OJBECT متساوية و hashcode. يتم استخدام هاتين الطريقتين لمقارنة ما إذا كان الكائنان متساويان.
لماذا يتعين علينا تجاوز طريقة Hashcode أثناء إعادة كتابة طريقة متساوية؟
يمكن فهمه على النحو التالي: بعد إعادة كتابة طريقة متساوية ، سيتغير منطق العمل للحكم على مساواة الأشياء. لا يريد مصمم الفصل مقارنة المساواة بين الكائنين من خلال مقارنة عنوان الذاكرة. لا معنى لها الاستمرار في المقارنة وفقًا للعنوان. لذلك ، يتم تغييره ببساطة معًا.
سبب آخر يأتي من مجموعات. لنتحدث عن ذلك ببطء أدناه ~
على سبيل المثال:
في المدرسة ، من خلال معرف الطالب لتحديد ما إذا كان هذا الشخص ينتمي إليه.
السيناريو الموجود في الكود أدناه هو إدخال سجل الطالب ، يتم تعيين رقم الطالب 123 للطالب توم ، ويتم تعيين رقم الطالب 456 للطالب جيري ، ويتم تعيين رقم الطالب 123 إلى Lily عن طريق الخطأ. ومع ذلك ، لا ينبغي أن يحدث رقم الطالب نفسه أثناء عملية تسجيل حالة الطالب.
اعتمادًا على المتطلبات الظرفية ، لا يمكن إضافة الكائنات المكررة ، ويمكن تنفيذها من خلال Hashset.
اختبار الفئة العامة {public static void main (string [] args) {student stu = new student (123 ، "TOM") ؛ Hashset <Studture> set = new hashset <> () ؛ set.add (stu) ؛ set.add (new student> (456 ، "jerry") بينما (iterator.hasnext ()) {student student = iterator.next () ؛ system.out.println (student.getStunum () + "---" + student.getName ()) ؛}}} ؛ طالب الفصل {private int und ؛ name public student ؛ public student (int strenum ، string ad} {this.stunum ؛ Boolean يساوي (كائن OBJ) {if (this == obj) إرجاع true ؛ if (obj extureof student) {if (this.getStunum () == ((الطالب) obj) .getStunum ()) إرجاع true ؛} false ؛}} الإخراج هو:
123 --- ليلي
456 --- جيري
123 --- توم
بناءً على الإخراج ، وجدنا أن تعيين رقم الطالب 123 إلى Lily نجح مرة أخرى. ما الخطأ؟
دعنا نلقي نظرة على طريقة إضافة Hashset:
إضافة منطقية عامة (e e) {return map.put (e ، present) == null ؛} في الواقع ، يتم تنفيذ hashset من خلال hashmap ، لذلك نتتبع طريقة وضع hashmap:
public v pum (k key ، v value) {if (table == leght_table) {inflateTable (عتبة) ؛} if (key == null) return putfornullkey (value) ؛ int hash = key) ؛ int i = indexfor (hash ، table.length) ؛ for (k ، v> e = hash && ((k = e.key) == مفتاح || key.equals (k))) {v oldvalue = e.value ؛ e.value = value ؛1. وفقًا للمفتاح ، أي الكائن الذي سيتم إضافته بواسطة Hashset ، واحصل على رمز hashcode ، ويتم استخدام رمز hashcode لإجراء عمليات بت محددة للحصول على رمز التجزئة ؛
2. استخدم تحديد موقع رمز التجزئة للعثور على مجموعة المصفوفة للحصول على رأس الارتباط للقائمة المرتبطة ؛
3. اجتياز القائمة المرتبطة لمعرفة ما إذا كان هناك نفس المفتاح. أساس الحكم هو e.hash == hash && ((k = e.key) == مفتاح || key.equals (k)). عند إضافة زنبق ، نظرًا لإعادة كتابة طريقة متساوية ، يجب أن تكون الحالة الثانية صحيحة عند عبور توم ؛ ولكن نظرًا لأن طريقة hashcode لا تزال تستخدم الفئة الأصل ، فإن رمز التجزئة من Tom و Lily مختلف ، أي ، رمز التجزئة مختلف ، والشرط الأول خطأ. هنا نحصل على أن الكائنين مختلفين ، لذا تضيف Hashset Lily بنجاح.
والسبب هو أن طريقة Hashcode لا يتم إعادة كتابة. هنا تعديل:
اختبار الفئة العامة {public static void main (string [] args) {student stu = new student (123 ، "TOM") ؛ Hashset <Studture> set = new hashset <> () ؛ set.add (stu) ؛ set.add (new student> (456 ، "jerry") بينما (iterator.hasnext ()) {student student = iterator.next () ؛ system.out.println (student.getStunum () + "---" + student.getName ()) ؛}}} ؛ طالب الفصل {private int und ؛ name public student ؛ public student (int strenum ، string ad} {this.stunum ؛ Boolean يساوي (كائن OBJ) {if (this == obj) إرجاع true ؛ if (obj extureof student) {if (this.getStunum () == ((الطالب) OBJ) .getStunum ()) إرجاع true ؛} الإخراج:
456 --- جيري
123 --- توم
أعد كتابة طريقة Hashcode وإرجاع رقم الطالب. حسنًا ، لقد تم ذلك.
قد يتساءل بعض الناس ، E.Hash == hash && ((k = e.key) == مفتاح || key.equals (k)) معقدة بعض الشيء؟ أعتقد أنه يكفي فقط استخدام طريقة متساوين. لماذا تحتاج إلى الحكم على Hashcode دفعة واحدة؟
لأنه عند عبورها والحكم في بنية القائمة المرتبطة بـ HashMap ، يكون منطق العمل الخاص بـ REBRITTEN Equals أكثر تعقيدًا لمقارنة ما إذا كانت الكائنات متساوية في مواقف محددة ، وسيؤثر منطق العمل في الحلقات لأسفل على كفاءة البحث. حتى هنا وضعنا حكم Hashcode أولاً. طالما أن Hashcode لم يكن متساويًا ، فسوف تنتهي من اللعب ، وليس هناك حاجة للاتصال بـ Complex Equals بعد الآن. تحسين كفاءة hashmap إلى حد كبير.
لذلك ، تتمثل طريقة HashCode في السماح لنا باستخدام فئات التجميع مثل HashMap بشكل طبيعي ، لأن HashMap تحدد ما إذا كانت الكائنات متساوية ، سواء من هذا القبيل ومتساوي المقارنة. هذا التنفيذ هو تحسين كفاءة hashmap.