1. Hashtable هي فئة فرعية من القاموس.
انسخ رمز الكود كما يلي:
جدول تصنيف الفئة العامة<K,V>
يمتد القاموس<K,V>
تنفذ Map<K,V>، Cloneable، java.io.Serializable
خريطة التجزئة:
انسخ رمز الكود كما يلي:
الفئة العامة HashMap<K,V>
يمتد AbstractMap<K,V>
ينفذ Map<K,V>، قابل للاستنساخ، قابل للتسلسل
يعد كل من HashMap وHashtable فئتي تنفيذ لواجهة الخريطة؛
2. الطرق في Hashtable متزامنة ()، لكن الطرق في HashMap غير متزامنة بشكل افتراضي. وهذا يعني أنه في التطبيقات متعددة الخيوط، يمكن استخدام Hashtable بأمان دون الحاجة إلى عمليات خاصة؛ وبالنسبة لـ HashMap، يلزم وجود آلية مزامنة إضافية. ولكن يمكن حل مشكلة مزامنة HashMap من خلال طريقة ثابتة للمجموعات:
انسخ رمز الكود كما يلي:
خريطة عامة ثابتة <K,V> <K,V> متزامنةMap(Map<K,V> m)
تقوم هذه الطريقة بإرجاع خريطة متزامنة، مما يعني أن الخريطة التي تم إرجاعها آمنة لمؤشر الترابط. تجدر الإشارة إلى أنه عند التكرار على الخريطة التي تم إرجاعها، يجب عليك المزامنة يدويًا على الخريطة التي تم إرجاعها، وإلا فسيؤدي ذلك إلى سلوك غير محدد:
انسخ رمز الكود كما يلي:
Map m = Collections.synchronizedMap(new HashMap());
...
Set s = m.keySet(); // لا يلزم أن يكون في كتلة متزامنة
...
متزامن (م) {// المزامنة على م، وليس على س!
Iterator i = s.iterator(); // يجب أن يكون في كتلة متزامنة
بينما (i.hasNext())
foo(i.next());
}
3. في HashMap، يمكن استخدام القيمة الخالية كمفتاح، ولا يوجد سوى مفتاح واحد من هذا القبيل؛ ويمكن أن يكون هناك مفتاح واحد أو أكثر تكون قيمته المقابلة فارغة. عندما تقوم طريقة get () بإرجاع قيمة فارغة، فقد يعني ذلك أن المفتاح غير موجود في HashMap، أو قد يعني أيضًا أن القيمة المقابلة للمفتاح فارغة. لذلك، في HashMap، لا يمكن استخدام طريقة get () لتحديد ما إذا كان هناك مفتاح معين موجود في HashMap، ولكن يجب استخدام طريقة يحتوي على مفتاح () لتحديد ما إذا كان هناك مفتاح معين موجود في HashMap. لا يمكن أن تكون القيمة الأساسية لـ Hashtable فارغة، وإلا: java.lang.NullPointerException.
4. يستخدم HashTable التعداد، ويستخدم HashMap Iterator.
ما ورد أعلاه ليس سوى اختلافات سطحية، كما أن تطبيقاتها مختلفة تمامًا.
5. الحجم الافتراضي لمصفوفة التجزئة في HashTable هو 11، وطريقة الزيادة قديمة*2+1. الحجم الافتراضي لمصفوفة التجزئة في HashMap هو 16، ويجب أن يكون أسه 2.
6. يختلف استخدام قيم التجزئة. يستخدم HashTable رمز التجزئة الخاص بالكائن مباشرة كما يلي:
انسخ رمز الكود كما يلي:
int hash = key.hashCode();
مؤشر int = (التجزئة & 0x7FFFFFFFF) % tab.length;
يقوم HashMap بإعادة حساب قيمة التجزئة ويستخدم AND بدلاً من المعامل، مثل طريقة put الخاصة بـ HashMap:
انسخ رمز الكود كما يلي:
وضع V العام (مفتاح K، قيمة V) {
إذا (مفتاح == فارغ)
إرجاع putForNullKey(value);
int hash = hash(key.hashCode());
int i = IndexFor(hash, table.length);
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
كائن ك؛
إذا (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
القيمة الإلكترونية = القيمة؛
e.recordAccess(this);
إرجاع القيمة القديمة؛
}
}
modCount++;
addEntry(hash, key, value, i);
عودة فارغة؛
}
انسخ رمز الكود كما يلي:
تجزئة كثافة العمليات الثابتة (int h) {
// تضمن هذه الوظيفة أن رموز التجزئة تختلف فقط حسب
// المضاعفات الثابتة في كل موضع بت لها حدود
// عدد الاصطدامات (حوالي 8 عند عامل التحميل الافتراضي).
ح ^= (ح >>> 20) ^ (ح >>> 12);
العودة ح ^ (ح >>> 7) ^ (ح >>> 4)؛
}
انسخ رمز الكود كما يلي:
مؤشر كثافة العمليات الثابت (Int h، int length) {
العودة ح & (الطول -1)؛
}