―hashmap-
المزايا: سرعة الاستعلام السريعة وهياكل البيانات التي يمكن أن تصل إلى O (1) تعقيد الوقت هو hashmap. بيانات التخزين المتغيرة ذات الطول المتغير (نسبة إلى المصفوفات).
العيوب: يجب حساب قيمة التجزئة بشكل إضافي ، وإذا لم يتم التعامل معها بشكل صحيح ، فستشغل مساحة إضافية.
- كيف لاستخدام HashMap-
عادة ما نستخدم hashmap على النحو التالي
خريطة <integer ، string> maps = new hashmap <integer ، string> () ؛ Maps.put (1 ، "A") ؛ Maps.put (2 ، "B") ؛
الرمز أعلاه ينشئ hashmap جديد ويدرج بيانات اثنين. لا يتم قبول أنواع البيانات الأساسية هنا للقيام K و V.
إذا كتبت هذا ، فستكون هناك مشاكل:
خريطة <int ، double> maps = new hashmap <int ، double> () ؛
لماذا نستخدم بهذه الطريقة؟ يرجى الاطلاع على رمز المصدر:
الطبقة العامة hashmap <k ، v> يمتد الملخصات <k ، v> تنفيذ خريطة <k ، v> ، استنساخ ، قابلة للتسلسل
هذا هو تعريف فئة تنفيذ hashmap.
hashmap هي بنية بيانات ذات طول متغير ديناميكي-
عند استخدام HashMap ، من أجل تحسين كفاءة التنفيذ ، غالبًا ما نضع سعة تهيئة HashMap:
خريطة <string ، string> rm = new hashmap <string ، string> (2)
أو استخدم خرائط فئة أدوات جوافا لإنشاء مجموعة بسهولة وتهيئة القيمة بالحجم المناسب.
خريطة <سلسلة ، كائن> خريطة = خرائط
فلماذا استخدامه مثل هذا؟ دعونا نلقي نظرة على مُنشئ المصدر.
مُنشئ بدون معلمات:
HASHMAP () {this.loadfactor = default_load_factor ؛ عتبة = (int) (default_initial_capacity * default_load_factor) ؛ جدول = إدخال جديد [default_initial_capacity] ؛ init () ؛ } hashmap () {
this.loadFactor = default_load_factor ؛
عتبة = (int) (default_initial_capacity * default_load_factor) ؛
جدول = إدخال جديد [default_initial_capacity] ؛
init () ؛
}
/** * يبني فارغًا <tt> hashmap </tt> مع السعة الأولية المحددة * وعامل التحميل الافتراضي (0.75). * * param initialCapacity السعة الأولية. * therws alfictalargumentException إذا كانت السعة الأولية سلبية. */ hashmap العامة (int initialCapacity) {this (initialCapacity ، default_load_factor) ؛ }شرح الأسماء:
default_load_factor // عامل التحميل الافتراضي ، 0.75 إذا لم يتم تحديده. default_initial_capacity // القدرة التهيئة الافتراضية ، يتم حساب القيمة الافتراضية الافتراضية // قيمة العتبة (YU) استنادًا إلى عامل التحميل وقدرة التهيئة. <span style = "color: RGB (54 ، 46 ، 43) ؛ Font-Family:" Microsoft Yahei "؛"> تعني العتبة أنه عندما يكون حجم hashmap أكبر من العتبة ، سيتم تنفيذ عملية تغيير الحجم.
لذلك نعلم أننا إذا اتصلنا بمنشئ المعلمة ، فسوف نحصل على صفيف من 16 سعة.
لذا فإن السؤال هو: ماذا لو كانت السعة الأولية ليست كافية؟
المصفوفات ثابتة طول ، وكيفية استخدام بيانات الطول الثابت لتمثيل البيانات غير المؤكدة؟ الجواب هو إيجاد واحد أطول ، ولكنه يقلل من الكفاءة عند تغيير حجمه. لذلك نوصي بإعطاء hashmap قدرة موثوقة عند التهيئة.
- وضع hashmap method-
public v put (k key ، v value) {if (key == null) // إذا كان المفتاح فارغًا ، فقد كان الفرق بين hashmap و hashtable putfornullkey (value) ؛ int hash = hash (key.hashCode ()) ؛ // تأطير قيمة التجزئة استنادًا إلى hashcode للمفتاح int i = indexfor (hash ، table.length) ؛ // تأطير ترجمة الصفيف التي يجب وضعها بناءً على قيمة التجزئة لـ (الإدخال <k ، v> e = table [i] ؛ e! = null ؛ e = if ( e.value = القيمة ؛ eRecordAccess (هذا) ؛ إرجاع Oldvalue ؛ }} modcount ++ ؛ // counter addentry (hash ، key ، value ، i) ؛ // إضافة إلى Array Return NULL ؛ }إذا تجاوزت البيانات المدرجة السعة الحالية ، فسيتم تنفيذها
addentry (التجزئة ، المفتاح ، القيمة ، i) ؛
addentry void (int hash ، k ، vale v ، int bucketIndex) {intrad <k ، v> e = table [bucketIndex] ؛ الجدول [bucketIndex] = إدخال جديد <k ، v> (التجزئة ، المفتاح ، القيمة ، e) ؛ if (size ++> = عتبة) <span style = "color:#ff0000 ؛"> <strong> تغيير حجم (2 * table.length) ؛}هنا ، إذا تم عرض عتبة Size ++> الحالية ، فسيتم توسيع الحجم الحالي مرتين وسيتم تنفيذ تغيير حجمه (2*Table.Length). فكيف يتوسعون؟
void تغيير حجم (int newCapacity) {entry [] oldtable = table ؛ int oldcapacity = oldtable.length ؛ if (oldcapacity == maximum_capacity) {threshold = integer.max_value ؛ يعود؛ } الإدخال [] newtable = إدخال جديد [newCapacity] ؛ <span style = "color: rgb (51 ، 51 ، 51) ؛ font-family: arial ؛"> جديد صفيف جديد ، </span> <strong> <span style = "color:#ff0000 ؛ عتبة = (int) (newCapacity * loadFactor) ؛ // إعادة حساب السعة}كيف يتم نقل نقل صفيف النقل؟
نقل void (إدخال [] newtable) {entry [] src = table ؛ int newCapacity = newtable.length ؛ لـ (int j = 0 ؛ j <src.length ؛ j ++) {entry <k ، v> e = src [j] ؛ if (e! = null) {src [j] = null ؛ do {entry <k ، v> next = e.next ؛ int i = <strong> <span style = "color:#ff0000 ؛"> indexfor (E.Hash ، NewCapacity) ؛ // إعادة حساب الفهرس بناءً على سعة قيمة التجزئة </span> </strong> e.next = newtable [i] ؛ Newtable [i] = e ؛ ه = التالي ؛ } بينما (e! = null) ؛ }}}- عدد عمليات الإعدام الإضافية لتوسيع هاشماب-
لذلك إذا أردنا إضافة HashMap من 1000 عنصر ، إذا استخدمنا القيمة الافتراضية ، فكم عدد الحسابات الإضافية التي أحتاج إلى حسابها؟
عندما يكون أكبر من 16*0.75 = 12 ، يجب إعادة حسابها 12 مرة
عندما يكون أكبر من 16*2*0.75 = 24 ، يلزم 24 حسابًا إضافيًا.
...
عندما يكون أكبر من 16*n*0.75 = 768 ، هناك حاجة إلى 768 حسابًا إضافيًا.
لذلك قمنا بحساب 12+24+48+...+768 مرة في عملية التوسع
لذلك ، يوصى بشدة أن نحدد يدويًا الحجم الأولي إذا عرفنا النطاق في المشروع مثل هذا:
Map <Integer ، String> Maps = New HashMap <Integer ، String> (1000) ؛
ملخص: هذا هو السبب في تقليل كفاءة تنفيذ hashmap بشدة إذا تجاوزت السعة الأولية أثناء الاستخدام.
ما سبق هو كل شيء عن استخدام HashMap في هذه المقالة حول تحليل رمز مصدر Java ، وآمل أن يكون مفيدًا للجميع. يمكن للأصدقاء المهتمين الاستمرار في الرجوع إلى الموضوعات الأخرى ذات الصلة على هذا الموقع. إذا كانت هناك أي أوجه قصور ، فيرجى ترك رسالة لإشارةها. شكرا لك يا أصدقائك لدعمكم لهذا الموقع!