تعيين في Java عبارة عن مجموعة لا تحتوي على عناصر مكررة ، أو أن تكون دقيقة ، زوج عنصر لا يحتوي على E1.equals (E2). لاغية مسموح بها في المجموعة. SET لا يمكن أن تضمن ترتيب العناصر في المجموعة.
عند إضافة عنصر لتعيينه ، إذا لم يكن العنصر المحدد موجودًا ، فإن الإضافة ناجحة. أي إذا لم يكن العنصر E1 موجودًا في المجموعة (e == null؟ e1 == null: e.quals (e1)) ، يمكن إضافة E1 إلى المجموعة.
فيما يلي مجموعة من فئة التنفيذ المحددة كمثال ، وتقدم بإيجاز مبدأ SET عدم تكرار التنفيذ:
package com.darren.test.overide ؛ الفئة العامة customString {private string value ؛ public customString () {this ("") ؛} public customString (قيمة السلسلة) {this.value = value ؛}} package com.darren.test.overide ؛ استيراد java.util.hashset ؛ استيراد java.util.set ؛ فئة عامة hashsettest {public static void main (string [] args) {string a = new string ("a") ؛ string b = new string ("a" CustomString ("B") ؛ system.out.println ("A.equals (b) ==" + A.Equals (b)) ؛ system.out.println ("c.equals (d) ==" + c.equals (d)) ؛ set <Object> set = new = new = new = hashset <Object> () ؛ set.add (a) ؛ set.add (b) ؛ set.add (c) ؛ set.add (d) ؛ system.out.println ("set.size () ==" + set.size ())نتائج التشغيل كما يلي:
A.equals (b) == true c.equals (d) == false set.size () == 3 com.darren.test.overide.customstring@2c39d2 a com.darren.test.overide.customstring@5795ce
ربما تكون قد رأيت المفتاح ، هذا صحيح ، إنها طريقة متساوية. لا يزال من غير المناسب أن نقول هذا ، ولكن أن يكون دقيقًا ، يجب أن يكون أساليب المساواة والرمز. لماذا تقول ذلك؟ دعونا نغير فئة CustomString ونختبرها:
package com.darren.test.overide ؛ الفئة العامة customString {private string value ؛ public customString () {this ("") ؛} public customString (قيمة السلسلة) {this.value = value ؛ obj ؛ return customString.value.equals (value) ؛} آخر {return false ؛}}}نتائج الاختبار:
A.equals (b) == true c.equals (d) == true set.size () == 3 com.darren.test.overide.customstring@12504e0 a com.darren.test.overide.customstring@1630b6
قيمة الإرجاع متساوية هذه المرة صحيحة ، لكن حجم المجموعة لا يزال 3.
دعونا نستمر في التغيير
package com.darren.test.overide ؛ الفئة العامة customString {private string value ؛ public customString () {this ("") ؛} public customString (قيمة السلسلة) {this.value = value ؛}@overide public int hashcode () {// return super.hashcode () ؛ العودة 1 ؛}}انظر إلى النتائج مرة أخرى:
A.equals (b) == true c.equals (d) == false set.size () == 3 com.darren.test.overide.customstring@1
إعادة كتابة طريقة Hashcode فقط ، وليس إعادة كتابة الطريقة ، إما
أخيرًا ، قم بتغييره
package com.darren.test.overide ؛ الفئة العامة customString {private string value ؛ public customString () {this ("") ؛} public customString (قيمة السلسلة) {this.value = value ؛ obj ؛ return customString.value.equals (value) ؛} else {return false ؛}}@override public int hashcode () {// return super.hashcode () ؛ العودة 1 ؛}}النتائج النهائية:
A.equals (b) == true c.equals (d) == true set.size () == 2 com.darren.test.overide.customstring@1 a
حسنًا ، لقد ثبت أنك تحتاج إلى إعادة كتابة طريقة متساوية وطريقة الترميز ، ومعرفة المبدأ:
اتفاقية Hashcode في java.lnag.object:
1. أثناء تنفيذ التطبيق ، إذا لم يتم تعديل المعلومات المستخدمة لمقارنة طريقة متساوية للكائن ، فإن طريقة HashCode تسمى عدة مرات على الكائن ، ويجب أن تعيد باستمرار نفس عدد صحيح.
2. إذا كان الكائنان متساويان وفقًا لطريقة متساوية (Objecto) ، فإن استدعاء طريقة Hashcode لأي من الكائنين يجب أن ينتجوا نفس نتيجة عدد صحيح.
3. إذا لم يكن الكائنان متساويان وفقًا لطريقة متساوية (Objecto) ، فسيتم استدعاء طريقة HashCode لأي من الكائنين ، ولا توجد نتائج عدد صحيح مختلف. ولكن إذا كان يمكن أن يكون مختلفًا ، فقد يحسن أداء جدول التجزئة.
في Hashset ، يتم تنفيذ العمليات الأساسية بواسطة طبقة HashMap ، لأن طبقة Hashset تستخدم HashMap لتخزين البيانات. عند إضافة عنصر إلى hashset ، قم أولاً بحساب قيمة Hashcode للعنصر ، ثم استخدم هذا (علامة التجزئة للعنصر) ٪ (حجم مجموعة hashmap) + 1 لحساب موقع التخزين لهذا العنصر. إذا كان هذا الموقف فارغًا ، أضف العنصر ؛ إذا لم يكن فارغًا ، فاستخدم طريقة متساوية لمقارنة ما إذا كانت العناصر متساوية ، وإذا كانت متساوية متساوية ، فلا تضيفها ، وإيجاد مساحة فارغة لإضافتها.
ما يلي جزء من رمز المصدر لشركة Hashset:
حزمة java.util ؛ فئة عامة hashset <e> يمتد ملخص <e> الأدوات المُعدة <e> ، clonable ، java.io.serializable {static final long serialversionuid = -5024744406713321676l ؛ hashmap عابر خاص <e ، كائن> خريطة ؛ // تحديد كائن افتراضي كقيمة للهاشمواب ، وتحديد هذا الكائن على أنه نهائي ثابت. الكائن النهائي الثابت الخاص الموجود = كائن جديد () ؛/*** تقوم بنية مُنشئ المعلمة الافتراضية ببناء تجزئة فارغة. * * في الواقع ، ستقوم الطبقة الأساسية بتهيئة hashmap فارغة وتستخدم السعة الأولية الافتراضية البالغة 16 وعامل التحميل 0.75. */public hashset () {map = new hashmap <e ، object> () ؛}/*** إنشاء مجموعة جديدة تحتوي على العناصر في المجموعة المحددة. * * تستخدم الطبقة الأساسية الفعلية عامل التحميل الافتراضي 0.75 وهي كافية لاحتواء السعة الأولية لجميع العناصر في المجموعة * المحددة لإنشاء hashmap. * param c سيتم تخزين العناصر الموجودة فيه في المجموعة في هذه المجموعة. */hashset العامة (مجموعة <يمتد e> c) {map = new hashmap <e ، object> (math.max ((int) (c.size ()/. 75f) + 1 ، 16)) ؛ addall (c) ؛}/*** بناء هاشف فارغ مع القدرات الأولية المحددة والتحميل. * * تقوم الطبقة الكامنة الفعلية ببناء hashmap فارغة مع المعلمات المقابلة. * param initialcapacity السعة الأولية. * @param loadfactor عامل تحميل. */hashset العامة (int initialcapacity ، float loadfactor) {map = new hashmap <e ، object> (initialCapacity ، loadfactor) ؛}/*** قم بإنشاء مجموعة من التجزئة الفارغة مع القدرة الأولية المحددة. * * في الواقع ، تقوم الطبقة الأساسية ببناء hashmap فارغ مع المعلمات المقابلة وعملية التحميل من 0.75. * param initialcapacity السعة الأولية. */hashset العامة (int initialCapacity) {map = new hashmap <e ، object> (initialCapacity) ؛}/*** قم بإنشاء مجموعة تجزئة ارتباط فارغة جديدة مع capataction و loadfactor المحددة. * هذا المنشئ هو إذن الوصول إلى الحزمة ولا يتعرض للجمهور. إنه في الواقع مجرد دعم لـ LinkedHashSet. * * في الواقع ، ستقوم الطبقة الأساسية ببناء مثيل LinkedHashMap فارغ مع المعلمات المحددة لتنفيذها. * param initialcapacity السعة الأولية. * @param loadfactor عامل تحميل. * Param Dummy Tag. */hashset (int initialcapacity ، float loadfactor ، dummy boolean) {map = new LinkedHashMap <e ، object> (initialCapacity ، loadfactor) ؛}/*** إرجاع التكرار الذي يكرر العناصر في هذه المجموعة. عناصر ترتيب الإرجاع ليست محددة. * * الطبقة الأساسية تستدعي فعليًا مفتاح HashMap الأساسي لإعادة جميع المفاتيح. * يمكن رؤية العناصر الموجودة في Hashset ، ولكن يتم تخزينها على مفتاح hashmap الأساسي ، ويتم تحديد القيمة بواسطة كائن كائن نهائي ثابت. * @إعادة تكرار العناصر في هذه المجموعة. */@Outride Public Iterator <E> iterator () {return map.keyset (). iterator () ؛}/*** إرجاع عدد العناصر في هذه المجموعة (قدرة المجموعة). * * تدعو الطبقة الأساسية في الواقع طريقة الحجم () من HashMap لإرجاع عدد الإدخال ، وتحصل على عدد العناصر في المجموعة. * العودة عدد العناصر في هذه المجموعة (سعة المجموعة). */@Override public int size () {return map.size () ؛}/*** return true إذا كانت هذه المجموعة لا تحتوي على أي عناصر. * * الطبقة الأساسية تستدعي فعليًا isempty () من hashmap لتحديد ما إذا كانت مجموعة التجزئة فارغة. * return return true إذا كانت هذه المجموعة لا تحتوي على أي عناصر. */@تجاوز عام Boolean Isempty () {return map.isempty () ؛}/*** إرجاع صحيح إذا كانت هذه المجموعة تحتوي على العنصر المحدد. * بشكل أكثر تحديداً ، يتم إرجاع TRUE إذا وفقط إذا كانت هذه المجموعة تحتوي على عنصر E يرضي (O == NULL؟ E == NULL: O.Equals (E)) *. * * يحدد يحتوي على مفتاح الدعوة الفعلية الأساسية لـ HashMap ما إذا كان يحتوي على المفتاح المحدد. * param o تم اختبار وجود العنصر في هذه المجموعة. * return return true إذا كانت هذه المجموعة تحتوي على العنصر المحدد. */@Override Public Boolean يحتوي على (كائن O) {return map.containskey (o) ؛}/*** إذا لم يتم تضمين العنصر المحدد في هذه المجموعة ، أضف العنصر المحدد. * بشكل أكثر تحديداً ، إذا كانت هذه المجموعة لا تحتوي على عنصر E2 الذي يرضي (e == null؟ e2 == NULL: E.equals (e2)) * ، تتم إضافة العنصر المحدد إلى هذه المجموعة. * إذا كانت هذه المجموعة تحتوي بالفعل على العنصر ، فإن المكالمة لا تغير المجموعة وتُرجع خطأ. * * سوف تضع الطبقة الأساسية في الواقع العنصر كمفتاح في hashmap. * نظرًا لأن طريقة PUT () من HashMap تضيف زوجًا من القيمة الرئيسية ، عندما يكون المفتاح في الإدخال الجديد من HashMap * هو نفس مفتاح الإدخال الأصلي في المجموعة (HASHCODE () ، فإن إرجاعه مساوٍ ، ويعود أيضًا إلى حد ما من خلال مقارنة متساوٍ) ، * ستعمل قيمة الإدخال المضافة حديثًا على كتابة قيمة الدخول الأصلية ، ولكن لن يتم تغيير المفتاح. * لذلك ، إذا تمت إضافة عنصر موجود إلى Hashset ، فلن يتم وضع عنصر التجميع المضافة حديثًا في HashMap ، ولن يتغير العنصر الأصلي أيًا ، والذي يفي بميزة عدم إعادة التثبيت في المجموعة. * @Param E عناصر سيتم إضافتها إلى هذه المجموعة. * return return true إذا كانت هذه المجموعة لا تحتوي على العنصر المحدد. */@Override Public Boolean Add (E E) {return map.put (e ، present) == null ؛}/*** إذا كان العنصر المحدد موجودًا في هذه المجموعة ، فسيتم إزالته. * بشكل أكثر تحديداً ، إذا كانت هذه المجموعة تحتوي على عنصر e يرضي (o == null؟ e == null: o.equals (e)) ، * سوف يزيله. إرجاع صحيح إذا كانت هذه المجموعة تحتوي بالفعل على العنصر (أو: صحيح إذا تغيرت هذه المجموعة بسبب المكالمة). (بمجرد إرجاع المكالمة ، لم تعد هذه المجموعة تحتوي على العنصر). * * تقوم الطبقة الأساسية بالفعل باستدعاء طريقة إزالة HashMap لحذف الإدخال المحدد. * param o كائن يجب إزالته إذا كان موجودًا في هذه المجموعة. * return return true إذا كان تعيينه يحتوي على العنصر المحدد. */@Override Public Boolean Remove (Object O) {return map.remove (o) == present ؛}/*** قم بإزالة جميع العناصر من هذه المجموعة. بعد عودة هذه المكالمة ، ستكون المجموعة فارغة. * * تدعو الطبقة الأساسية في الواقع الطريقة الواضحة لـ HashMap لمسح جميع العناصر في الدخول. */@Override public void clear () {map.clear () ؛}}لخص
ما سبق هو كل محتوى هذه المقالة حول تحليل مبدأ إزالة Hashset للقيم المكررة. آمل أن يكون ذلك مفيدًا للجميع. يمكن للأصدقاء المهتمين الاستمرار في الرجوع إلى الموضوعات الأخرى ذات الصلة على هذا الموقع. إذا كانت هناك أي أوجه قصور ، فيرجى ترك رسالة لإشارةها. شكرا لك يا أصدقائك لدعمكم لهذا الموقع!