الاختلافات بين HashMap وHashtable؟
-
09-06-2019 - |
المحلول
هناك عدة اختلافات بين HashMap
و Hashtable
في جافا:
Hashtable
يكون متزامن, ، بينماHashMap
ليس.هذا يجعلHashMap
أفضل للتطبيقات غير المترابطة، حيث أن الكائنات غير المتزامنة عادةً ما تكون أفضل من تلك المتزامنة.Hashtable
لا يسمحnull
المفاتيح أو القيم.HashMap
يسمح لأحدnull
المفتاح وأي عدد منnull
قيم.إحدى الفئات الفرعية لـ HashMap هي
LinkedHashMap
, ، لذلك في حالة رغبتك في ترتيب تكرار يمكن التنبؤ به (وهو ترتيب الإدراج افتراضيًا)، يمكنك بسهولة تبديلHashMap
لLinkedHashMap
.لن يكون هذا سهلاً إذا كنت تستخدمهHashtable
.
وبما أن المزامنة لا تمثل مشكلة بالنسبة لك، فإنني أوصي بذلك HashMap
.إذا أصبحت المزامنة مشكلة، فيمكنك أيضًا الاطلاع على ConcurrentHashMap
.
نصائح أخرى
لاحظ أن الكثير من الإجابات تشير إلى أن Hashtable متزامن. في الممارسة العملية، هذا لا يشتري لك سوى القليل جدًا. ستؤدي المزامنة على أساليب الوصول / المحوّل إلى إيقاف إضافة خيطين أو إزالتهما من الخريطة بشكل متزامن، ولكن في العالم الحقيقي ستحتاج غالبًا إلى مزامنة إضافية.
المصطلح الشائع جدًا هو "التحقق ثم ضع" - أي.ابحث عن إدخال في Map
, ، وإضافته إذا لم يكن موجودًا بالفعل.هذه ليست بأي حال من الأحوال عملية ذرية سواء كنت تستخدمها Hashtable
أو HashMap
.
متزامنة على قدم المساواة HashMap
يمكن الحصول عليها عن طريق:
Collections.synchronizedMap(myMap);
ولكن لتنفيذ هذا المنطق بشكل صحيح تحتاج مزامنة إضافية النموذج:
synchronized(myMap) {
if (!myMap.containsKey("tomato"))
myMap.put("tomato", "red");
}
حتى التكرار على أ Hashtable
إدخالات (أو أ HashMap
حصل عليها Collections.synchronizedMap
) ليس آمنًا إلا إذا كنت تحرس أيضًا Map
من التعديل من خلال المزامنة الإضافية.
تنفيذات ال ConcurrentMap
الواجهة (على سبيل المثال ConcurrentHashMap
) حل بعض من هذا عن طريق تضمين دلالات الخيط الآمن للتحقق ثم التصرف مثل:
ConcurrentMap.putIfAbsent(key, value);
Hashtable
يعتبر رمزًا قديمًا.لا يوجد شيء حول Hashtable
لا يمكن القيام بذلك باستخدام HashMap
أو مشتقات HashMap
, ، لذلك بالنسبة للكود الجديد، لا أرى أي مبرر للعودة إليه Hashtable
.
غالبًا ما يتم طرح هذا السؤال في المقابلة للتحقق مما إذا كان المرشح يفهم الاستخدام الصحيح لفئات التحصيل وعلى دراية بالحلول البديلة المتاحة.
- فئة HashMap تعادل تقريبًا Hashtable، باستثناء أنها غير متزامنة وتسمح بالقيم الخالية.(يسمح HashMap بالقيم الخالية كمفتاح وقيمة بينما لا يسمح Hashtable بالقيم الخالية).
- لا يضمن HashMap بقاء ترتيب الخريطة ثابتًا بمرور الوقت.
- HashMap غير متزامن بينما تتم مزامنة Hashtable.
- يعتبر التكرار في HashMap آمنًا من الفشل بينما العداد الخاص بـ Hashtable ليس كذلك ويرمي ConcurrentModificationException إذا قام أي مؤشر ترابط آخر بتعديل الخريطة هيكليًا عن طريق إضافة أو إزالة أي عنصر باستثناء طريقة الإزالة () الخاصة بـ Iterator.لكن هذا ليس سلوكًا مضمونًا وسيتم تنفيذه بواسطة JVM بأقصى جهد.
ملاحظة على بعض الشروط الهامة
- المزامنة تعني أن مؤشر ترابط واحد فقط يمكنه تعديل جدول التجزئة في وقت واحد.في الأساس، هذا يعني أن أي مؤشر ترابط قبل إجراء تحديث على جدول التجزئة سيتعين عليه الحصول على قفل على الكائن بينما سينتظر الآخرون حتى يتم تحرير القفل.
- تعتبر الحماية من الفشل ذات صلة بسياق التكرارات.إذا تم إنشاء مكرر على كائن مجموعة وحاول مؤشر ترابط آخر تعديل كائن المجموعة "بنيويًا"، فسيتم طرح استثناء التعديل المتزامن.من الممكن أن تستدعي سلاسل الرسائل الأخرى طريقة "set" لأنها لا تقوم بتعديل المجموعة "هيكليًا".ومع ذلك، إذا تم تعديل المجموعة هيكليًا قبل استدعاء "set"، فسيتم طرح "IllegalArgumentException".
- التعديل الهيكلي يعني حذف أو إدراج عنصر يمكن أن يغير بنية الخريطة بشكل فعال.
يمكن مزامنة HashMap بواسطة
Map m = Collections.synchronizeMap(hashMap);
يوفر MAP طرق عرض التجميع بدلاً من الدعم المباشر للتكرار عبر كائنات التعداد.تعزز مشاهدات التجميع بشكل كبير التعبير عن الواجهة ، كما تمت مناقشته لاحقًا في هذا القسم.تتيح لك الخريطة التكرار على المفاتيح أو القيم أو أزواج القيمة الرئيسية؛لا يوفر Hashtable الخيار الثالث.توفر الخريطة طريقة آمنة لإزالة الإدخالات في خضم التكرار ؛لم يفعل ذلك Hashtable.وأخيرًا، يعمل Map على إصلاح عيب بسيط في واجهة Hashtable.يحتوي علامة التجزئة على طريقة تسمى ، والتي تُرجع صحيحًا إذا كان علامة التجزئة تحتوي على قيمة معينة.بالنظر إلى اسمها ، تتوقع أن تعود هذه الطريقة بشكل صحيح إذا احتوت علامة التصنيف على مفتاح معين ، لأن المفتاح هو آلية الوصول الأساسي للهاوية.تزيل واجهة الخريطة هذا المصدر للارتباك عن طريق إعادة تسمية الطريقة التي تحتوي على قيمة.أيضا ، هذا يحسن اتساق الواجهة - يحتوي على أوجه التشابه في القيمة.
HashMap
:تنفيذاً لل Map
الواجهة التي تستخدم رموز التجزئة لفهرسة مصفوفة.Hashtable
:مرحبا، 1998 اتصل.إنهم يريدون استعادة API لمجموعاتهم.
على الرغم من ذلك، من الأفضل أن تبتعد عنه Hashtable
كليا.بالنسبة للتطبيقات ذات الترابط الواحد، لا تحتاج إلى الحمل الإضافي للمزامنة.بالنسبة للتطبيقات المتزامنة للغاية، قد تؤدي المزامنة المذعورة إلى المجاعة أو الجمود أو التوقف المؤقت غير الضروري لجمع البيانات المهملة.كما أشار تيم هاولاند، قد تستخدم ConcurrentHashMap
بدلاً من.
لا تنسى HashTable
كانت فئة قديمة قبل تقديم Java Collections Framework (JCF) وتم تعديلها لاحقًا لتنفيذ Map
واجهه المستخدم.هكذا كان Vector
و Stack
.
لذلك، ابتعد دائمًا عنها في الكود الجديد نظرًا لوجود بديل أفضل دائمًا في JCF كما أشار آخرون.
هنا هو ورقة الغش لمجموعة جافا التي سوف تجدها مفيدة.لاحظ أن الكتلة الرمادية تحتوي على الفئة القديمة HashTable وVector وStack.
وبالإضافة إلى ما قاله عزب، HashMap
يسمح بالقيم الخالية، في حين أن Hashtable
لا.
لاحظ ذلك أيضًا Hashtable
يمتد Dictionary
الطبقة، والتي كما جافادوكس الدولة، عفا عليها الزمن وتم استبدالها بـ Map
واجهه المستخدم.
هناك العديد من الإجابات الجيدة التي تم نشرها بالفعل.أقوم بإضافة بعض النقاط الجديدة وتلخيصها.
HashMap
و Hashtable
كلاهما يستخدم للتخزين البيانات في شكل المفتاح والقيمة.كلاهما يستخدم تقنية التجزئة لتخزين المفاتيح الفريدة.ولكن هناك العديد من الاختلافات بين فئات HashMap وHashtable الموضحة أدناه.
خريطة التجزئة
HashMap
غير متزامن.إنه ليس آمنًا للخيوط ولا يمكن مشاركته بين العديد من سلاسل الرسائل دون رمز المزامنة المناسب.HashMap
يسمح بمفتاح فارغ واحد وقيم فارغة متعددة.HashMap
هي فئة جديدة تم تقديمها في JDK 1.2.HashMap
سريع.- يمكننا أن نجعل
HashMap
كما تمت مزامنته عن طريق استدعاء هذا الرمز
Map m = Collections.synchronizedMap(HashMap);
HashMap
تم اجتيازه بواسطة Iterator.- مكرر في
HashMap
سريع الفشل. HashMap
يرث فئة AbstractMap.
جدول التجزئة
Hashtable
تتم مزامنة.إنه آمن للخيوط ويمكن مشاركته مع العديد من المواضيع.Hashtable
لا يسمح بأي مفتاح أو قيمة فارغة.Hashtable
هي فئة تراث.Hashtable
بطيء.Hashtable
متزامن داخليًا ولا يمكن إلغاء مزامنته.Hashtable
يتم اجتيازها بواسطة Enumerator و Iterator.- العداد في
Hashtable
ليس سريع الفشل. Hashtable
يرث فئة القاموس.
قراءة متعمقة ما الفرق بين HashMap و Hashtable في Java؟
نلقي نظرة على هذا الرسم البياني.يوفر مقارنات بين هياكل البيانات المختلفة إلى جانب HashMap وHashtable.المقارنة دقيقة وواضحة وسهلة الفهم.
Hashtable
يشبه HashMap
ولديه واجهة مماثلة.فمن المستحسن أن تستخدم HashMap
, ، إلا إذا كنت بحاجة إلى دعم للتطبيقات القديمة أو كنت بحاجة إلى المزامنة، كما هو الحال في Hashtables
تتم مزامنة الأساليب.لذلك في حالتك لأنك لست متعدد الخيوط، HashMaps
هي أفضل رهان.
هناك اختلاف رئيسي آخر بين hashtable و hashmap وهو أن Iterator في HashMap سريع الفشل بينما العداد الخاص بـ Hashtable ليس كذلك ويرمي ConcurrentModificationException إذا قام أي مؤشر ترابط آخر بتعديل الخريطة هيكليًا عن طريق إضافة أو إزالة أي عنصر باستثناء طريقة الإزالة () الخاصة بـ Iterator.لكن هذا ليس سلوكًا مضمونًا وسيتم تنفيذه بواسطة JVM بأقصى جهد."
مصدري: http://javarevisited.blogspot.com/2010/10/difference-between-hashmap-and.html
إلى جانب جميع الجوانب المهمة الأخرى التي سبق ذكرها هنا، واجهة API للمجموعات (على سبيل المثال:يتم تعديل واجهة الخريطة) طوال الوقت لتتوافق مع الإضافات "الأحدث والأكبر" لمواصفات Java.
على سبيل المثال، قارن تكرار خريطة Java 5:
for (Elem elem : map.keys()) {
elem.doSth();
}
مقابل نهج Hashtable القديم:
for (Enumeration en = htable.keys(); en.hasMoreElements(); ) {
Elem elem = (Elem) en.nextElement();
elem.doSth();
}
في Java 1.8، وعدنا أيضًا بأن نكون قادرين على إنشاء HashMaps والوصول إليه كما هو الحال في لغات البرمجة النصية القديمة الجيدة:
Map<String,Integer> map = { "orange" : 12, "apples" : 15 };
map["apples"];
تحديث: لا، لن يهبطوا في 1.8...:(
HashTable متزامن، إذا كنت تستخدمه في موضوع واحد يمكنك استخدامه خريطة التجزئة, ، وهي نسخة غير متزامنة.غالبًا ما تكون الكائنات غير المتزامنة أكثر أداءً قليلاً.بالمناسبة، إذا وصلت عدة سلاسل رسائل إلى HashMap بشكل متزامن، وقام واحد على الأقل من الخيوط بتعديل الخريطة هيكليًا، فيجب مزامنتها خارجيًا.يمكنك التفاف خريطة غير متزامنة في خريطة متزامنة باستخدام:
Map m = Collections.synchronizedMap(new HashMap(...));
يمكن أن يحتوي HashTable على كائن غير فارغ فقط كمفتاح أو كقيمة.يمكن أن يحتوي HashMap على مفتاح فارغ واحد وقيم فارغة.
التكرارات التي يتم إرجاعها بواسطة الخريطة سريعة الفشل، إذا تم تعديل الخريطة هيكليًا في أي وقت بعد إنشاء المكرر، بأي طريقة باستثناء طريقة الإزالة الخاصة بالمكرر، فسوف يرمي المكرر
ConcurrentModificationException
.وبالتالي، في مواجهة التعديل المتزامن، يفشل المُكرِّر بسرعة وبشكل نظيف، بدلاً من المخاطرة بسلوك تعسفي وغير حتمي في وقت غير محدد في المستقبل. بينما التعدادات التي يتم إرجاعها بواسطة مفاتيح وأساليب عناصر Hashtable ليست سريعة الفشل.HashTable وHashMap عضوان في إطار مجموعات جافا (منذ الإصدار 1.2 من نظام Java 2، تم تحديث HashTable لتنفيذ واجهة الخريطة).
يعتبر HashTable رمزًا قديمًا، وتنصح الوثائق باستخدامه ConcurrentHashMap بدلاً من Hashtable إذا كان التنفيذ الآمن والمتزامن للغاية مطلوبًا.
لا يضمن HashMap الترتيب الذي يتم به إرجاع العناصر.بالنسبة لـ HashTable، أعتقد أن الأمر نفسه ولكني لست متأكدًا تمامًا، ولا أجد مصدرًا يوضح ذلك بوضوح.
HashMap
و Hashtable
لديها اختلافات خوارزمية كبيرة كذلك.لم يذكر أحد هذا من قبل ولهذا السبب أطرحه. HashMap
سيتم إنشاء جدول تجزئة بقوة ذات حجمين، وزيادته ديناميكيًا بحيث يكون لديك على الأكثر حوالي ثمانية عناصر (تصادمات) في أي مجموعة وستقوم بتحريك العناصر جيدًا لأنواع العناصر العامة.ومع ذلك، Hashtable
يوفر التنفيذ تحكمًا أفضل وأدق في التجزئة إذا كنت تعرف ما تفعله، أي أنه يمكنك إصلاح حجم الجدول باستخدام على سبيل المثال.أقرب رقم أولي إلى حجم مجال القيم الخاص بك وسيؤدي ذلك إلى أداء أفضل من HashMap، أي.تصادمات أقل في بعض الحالات.
بصرف النظر عن الاختلافات الواضحة التي تمت مناقشتها على نطاق واسع في هذا السؤال، أرى Hashtable كسيارة "محرك يدوي" حيث يمكنك التحكم بشكل أفضل في التجزئة وHashMap كنظير "محرك تلقائي" والذي سيعمل بشكل جيد بشكل عام.
تتم مزامنة Hashtable، بينما لا تتم مزامنة HashMap.وهذا يجعل Hashtable أبطأ من Hashmap.
بالنسبة للتطبيقات غير المترابطة، استخدم HashMap لأنها متماثلة من حيث الوظيفة.
بناء على المعلومات هنا, ، أوصي باستخدام HashMap.أعتقد أن الميزة الأكبر هي أن Java ستمنعك من تعديلها أثناء تكرارها، إلا إذا قمت بذلك من خلال المكرّر.
أ Collection
- تسمى أحيانًا الحاوية - هي ببساطة كائن يجمع عناصر متعددة في وحدة واحدة. Collection
تُستخدم لتخزين البيانات المجمعة واسترجاعها ومعالجتها وتوصيلها.إطار المجموعات دبليو هي بنية موحدة لتمثيل المجموعات ومعالجتها.
ال HashMap
JDK1.2
والهاشتابل JDK1.0
, ، يتم استخدام كلاهما لتمثيل مجموعة من الكائنات الممثلة فيها <Key, Value>
زوج.كل <Key, Value>
يسمى الزوج Entry
هدف.تتم الإشارة إلى مجموعة الإدخالات بواسطة كائن HashMap
و Hashtable
.يجب أن تكون المفاتيح الموجودة في المجموعة فريدة أو مميزة.[حيث يتم استخدامها لاسترداد قيمة معينة بمفتاح معين.يمكن تكرار القيم الموجودة في المجموعة.]
« عضو Superclass و Legacy و Collection Framework
Hashtable هي فئة قديمة تم تقديمها في JDK1.0
, ، وهي فئة فرعية من فئة القاموس.من JDK1.2
تمت إعادة تصميم Hashtable لتنفيذ واجهة الخريطة لجعل عضوا في إطار المجموعة.يعد HashMap عضوًا في Java Collection Framework منذ بداية تقديمه JDK1.2
.HashMap هي فئة فرعية من فئة AbstractMap.
public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, Serializable { ... }
public class HashMap<K,V> extends AbstractMap<K,V> implements Map<K,V>, Cloneable, Serializable { ... }
« السعة الأولية وعامل الحمولة
السعة هي عدد الدلاء في جدول التجزئة، والقدرة الأولية هي ببساطة السعة في وقت إنشاء جدول التجزئة.لاحظ أن جدول التجزئة مفتوح:في حالة "hash
collision
"، يقوم دلو واحد بتخزين إدخالات متعددة، والتي يجب البحث عنها بشكل تسلسلي.عامل التحميل هو مقياس لمدى امتلاء جدول التجزئة قبل زيادة سعته تلقائيًا.
يقوم HashMap بإنشاء جدول تجزئة فارغ بالسعة الأولية الافتراضية (16) وعامل الحمولة الافتراضي (0.75).حيث يقوم Hashtable بإنشاء جدول تجزئة فارغ بسعة أولية افتراضية (11) وعامل الحمولة/نسبة الملء (0.75).
« التعديل الهيكلي في حالة تصادم التجزئة
HashMap
, Hashtable
في حالة حدوث تصادمات التجزئة، يقومون بتخزين إدخالات الخريطة في قوائم مرتبطة. من Java8 ل HashMap
إذا زاد حجم دلو التجزئة عن حد معين، فسيتم التبديل من هذا الدلو linked list of entries to a balanced tree
.والتي تعمل على تحسين الأداء الأسوأ من O(n) إلى O(log n).أثناء تحويل القائمة إلى شجرة ثنائية، يتم استخدام رمز التجزئة كمتغير متفرع.إذا كان هناك رمزان مختلفان في نفس المجموعة، فسيتم اعتبار أحدهما أكبر وينتقل إلى يمين الشجرة والآخر إلى اليسار.ولكن عندما يكون كلا رمزي التجزئة متساويين، HashMap
يفترض أن المفاتيح قابلة للمقارنة، ويقارن المفتاح لتحديد الاتجاه بحيث يمكن الحفاظ على بعض النظام.إنها ممارسة جيدة أن تصنع المفاتيح HashMap
قابلة للمقارنة.عند إضافة الإدخالات إذا وصل حجم الجرافة TREEIFY_THRESHOLD = 8
تحويل قائمة الإدخالات المرتبطة إلى شجرة متوازنة، عند إزالة الإدخالات الأقل من TREEIFY_THRESHOLD
وعلى الأكثر UNTREEIFY_THRESHOLD = 6
سيعيد تحويل الشجرة المتوازنة إلى قائمة الإدخالات المرتبطة. جافا 8 إس آر سي, كومبوست
« تكرار عرض المجموعة، والفشل السريع والآمن للفشل
+--------------------+-----------+-------------+
| | Iterator | Enumeration |
+--------------------+-----------+-------------+
| Hashtable | fail-fast | safe |
+--------------------+-----------+-------------+
| HashMap | fail-fast | fail-fast |
+--------------------+-----------+-------------+
| ConcurrentHashMap | safe | safe |
+--------------------+-----------+-------------+
Iterator
هو فشل سريع في الطبيعة.أي أنه يطرح ConcurrentModificationException إذا تم تعديل المجموعة أثناء التكرار بخلاف طريقة الإزالة () الخاصة بها.بينما Enumeration
آمنة من الفشل في الطبيعة.لا يرمي أي استثناءات إذا تم تعديل المجموعة أثناء التكرار.
وفقًا لـ Java API Docs، يُفضل دائمًا استخدام Iterator على التعداد.
ملحوظة: يتم تكرار وظيفة واجهة التعداد بواسطة واجهة Iterator.بالإضافة إلى ذلك، يضيف Iterator عملية إزالة اختيارية، وله أسماء طرق أقصر.يجب أن تفكر التطبيقات الجديدة في استخدام Iterator بدلاً من Enumeration.
في قدمت Java 5 واجهة ConcurrentMap: ConcurrentHashMap
- متزامنة للغاية وعالية الأداء ConcurrentMap
التنفيذ مدعومًا بجدول التجزئة.لا يحظر هذا التطبيق مطلقًا إجراء عمليات الاسترداد ويسمح للعميل بتحديد مستوى التزامن للتحديثات.الغرض منه هو أن يكون بديلاً مباشرًا لـ Hashtable
:بالإضافة إلى التنفيذ ConcurrentMap
, ، فهو يدعم جميع الأساليب "القديمة" الخاصة بـ Hashtable
.
كل
HashMapEntry
القيمة هي متقلب وبالتالي ضمان اتساق الحبوب الدقيقة للتعديلات المتنازع عليها والقراءات اللاحقة؛تعكس كل قراءة آخر تحديث تم إكمالهالتكرارات والتعدادات آمنة من الفشل - تعكس الحالة في مرحلة ما منذ إنشاء المكرر/التعداد؛وهذا يسمح بالقراءات والتعديلات المتزامنة على حساب تقليل الاتساق.لا يقومون برمي ConcurrentModificationException.ومع ذلك، تم تصميم التكرارات ليتم استخدامها بواسطة مؤشر ترابط واحد فقط في المرة الواحدة.
يحب
Hashtable
ولكن خلافا لHashMap
, ، لا تسمح هذه الفئة باستخدام القيمة الخالية كمفتاح أو قيمة.
public static void main(String[] args) {
//HashMap<String, Integer> hash = new HashMap<String, Integer>();
Hashtable<String, Integer> hash = new Hashtable<String, Integer>();
//ConcurrentHashMap<String, Integer> hash = new ConcurrentHashMap<>();
new Thread() {
@Override public void run() {
try {
for (int i = 10; i < 20; i++) {
sleepThread(1);
System.out.println("T1 :- Key"+i);
hash.put("Key"+i, i);
}
System.out.println( System.identityHashCode( hash ) );
} catch ( Exception e ) {
e.printStackTrace();
}
}
}.start();
new Thread() {
@Override public void run() {
try {
sleepThread(5);
// ConcurrentHashMap traverse using Iterator, Enumeration is Fail-Safe.
// Hashtable traverse using Enumeration is Fail-Safe, Iterator is Fail-Fast.
for (Enumeration<String> e = hash.keys(); e.hasMoreElements(); ) {
sleepThread(1);
System.out.println("T2 : "+ e.nextElement());
}
// HashMap traverse using Iterator, Enumeration is Fail-Fast.
/*
for (Iterator< Entry<String, Integer> > it = hash.entrySet().iterator(); it.hasNext(); ) {
sleepThread(1);
System.out.println("T2 : "+ it.next());
// ConcurrentModificationException at java.util.Hashtable$Enumerator.next
}
*/
/*
Set< Entry<String, Integer> > entrySet = hash.entrySet();
Iterator< Entry<String, Integer> > it = entrySet.iterator();
Enumeration<Entry<String, Integer>> entryEnumeration = Collections.enumeration( entrySet );
while( entryEnumeration.hasMoreElements() ) {
sleepThread(1);
Entry<String, Integer> nextElement = entryEnumeration.nextElement();
System.out.println("T2 : "+ nextElement.getKey() +" : "+ nextElement.getValue() );
//java.util.ConcurrentModificationException at java.util.HashMap$HashIterator.nextNode
// at java.util.HashMap$EntryIterator.next
// at java.util.Collections$3.nextElement
}
*/
} catch ( Exception e ) {
e.printStackTrace();
}
}
}.start();
Map<String, String> unmodifiableMap = Collections.unmodifiableMap( map );
try {
unmodifiableMap.put("key4", "unmodifiableMap");
} catch (java.lang.UnsupportedOperationException e) {
System.err.println("UnsupportedOperationException : "+ e.getMessage() );
}
}
static void sleepThread( int sec ) {
try {
Thread.sleep( 1000 * sec );
} catch (InterruptedException e) {
e.printStackTrace();
}
}
« المفاتيح الخالية والقيم الخالية
HashMap
يسمح بحد أقصى لمفتاح فارغ واحد وأي عدد من القيم الخالية.بينما Hashtable
لا يسمح حتى بمفتاح فارغ واحد وقيمة فارغة، إذا كان المفتاح أو القيمة فارغة، فسيتم طرح NullPointerException. مثال
« متزامن، موضوع آمن
Hashtable
تتم مزامنته داخليًا.لذلك، فهو آمن جدًا للاستخدام Hashtable
في تطبيقات متعددة الخيوط.بينما HashMap
غير متزامن داخليا.لذلك، فهو غير آمن للاستخدام HashMap
في التطبيقات متعددة الخيوط دون مزامنة خارجية.يمكنك مزامنة خارجيا HashMap
استخدام Collections.synchronizedMap()
طريقة.
« أداء
مثل Hashtable
متزامنة داخليا، وهذا يجعل Hashtable
أبطأ قليلا من HashMap
.
@يرى
بالنسبة للتطبيقات المترابطة، يمكنك غالبًا التخلص من ConcurrentHashMap - اعتمادًا على متطلبات الأداء لديك.
1.Hashmap
و HashTable
كل من مفتاح المتجر والقيمة.
2.Hashmap
يمكن تخزين مفتاح واحد كما null
. Hashtable
لا يمكن تخزينها null
.
3.HashMap
غير متزامن ولكن Hashtable
تتم مزامنة.
4.HashMap
يمكن أن تكون متزامنة مع Collection.SyncronizedMap(map)
Map hashmap = new HashMap();
Map map = Collections.SyncronizedMap(hashmap);
وبصرف النظر عن الاختلافات التي سبق ذكرها، تجدر الإشارة إلى أنه منذ Java 8، HashMap
يستبدل ديناميكيًا العقد (القائمة المرتبطة) المستخدمة في كل مجموعة بـ TreeNodes (شجرة حمراء-سوداء)، لذلك حتى في حالة وجود تصادمات عالية، فإن الحالة الأسوأ عند البحث يكون
O(سجل(ن)) ل HashMap
ضد يا (ن) في Hashtable
.
*لم يتم تطبيق التحسين المذكور أعلاه Hashtable
بعد، ولكن فقط ل HashMap
, LinkedHashMap
, ، و ConcurrentHashMap
.
لمعلوماتك، حاليا،
TREEIFY_THRESHOLD = 8
:إذا كان الدلو يحتوي على أكثر من 8 عقد، فسيتم تحويل القائمة المرتبطة إلى شجرة متوازنة.UNTREEIFY_THRESHOLD = 6
:عندما يصبح الدلو صغيرًا جدًا (بسبب الإزالة أو تغيير الحجم)، يتم تحويل الشجرة مرة أخرى إلى القائمة المرتبطة.
هناك 5 اختلافات أساسية بين HashTable وHashMaps.
- تتيح لك الخرائط تكرار واسترداد المفاتيح والقيم وأزواج القيمة الرئيسية أيضًا، حيث لا يتمتع HashTable بكل هذه الإمكانية.
- يوجد في Hashtable وظيفة تحتوي على () وهي مربكة جدًا للاستخدام.لأن معنى يحتوي انحراف طفيف.هل يعني أنه يحتوي على مفتاح أو يحتوي على قيمة؟من الصعب أن نفهم.نفس الشيء في الخرائط لدينا وظائف يحتوي على مفتاح () ويحتوي على قيمة ()، والتي من السهل جدًا فهمها.
- في hashmap، يمكنك إزالة العنصر أثناء التكرار بأمان.حيث أنه ليس من الممكن في hashtables.
- تتم مزامنة HashTables بشكل افتراضي، لذلك يمكن استخدامها مع سلاسل رسائل متعددة بسهولة.حيث لا تتم مزامنة HashMaps افتراضيًا، لذلك يمكن استخدامها مع مؤشر ترابط واحد فقط.ولكن لا يزال بإمكانك تحويل HashMap إلى متزامن باستخدام وظيفة SynchronizedMap(Map m) الخاصة بفئة Collections util.
- لن يسمح HashTable بالمفاتيح الخالية أو القيم الخالية.حيث يسمح HashMap بمفتاح فارغ واحد وقيم فارغة متعددة.
مشاركتي البسيطة :
الفرق الأول والأهم بين
Hashtable
وHashMap
هل هذا،HashMap
ليست آمنة للخيط في حينHashtable
هي مجموعة آمنة للخيط.الفرق الثاني المهم بين
Hashtable
وHashMap
هو الأداء، منذ ذلك الحينHashMap
غير متزامنة أداء أفضل منHashtable
.الفرق الثالث على
Hashtable
ضدHashMap
هل هذاHashtable
فئة قديمة ويجب أن تستخدمهاConcurrentHashMap
بدلا منHashtable
في جافا.
HashTable هي فئة قديمة في jdk لا ينبغي استخدامها بعد الآن.استبدل استخداماتها بـ ConcurrentHashMap.إذا كنت لا تحتاج إلى سلامة الخيط، استخدم خريطة التجزئة وهو ليس كذلك Threadsafe ولكن بشكل أسرع ويستخدم ذاكرة أقل.
1) تتم مزامنة Hashtable بينما لا تتم مزامنة hashmap.2) هناك اختلاف آخر وهو أن المكرر في HashMap آمن من الفشل بينما العداد الخاص بـ Hashtable ليس كذلك.إذا قمت بتغيير الخريطة أثناء التكرار، ستعرف.
3) يسمح HashMap بالقيم الخالية فيه، بينما لا يسمح Hashtable بذلك.
HashMap وHashTable
- بعض النقاط المهمة حول HashMap وHashTable.يرجى قراءة التفاصيل أدناه.
1) Hashtable و Hashmap تنفيذ Java.Util.Map Interface 2) كلا من hashmap و hashtable هي المجموعة القائمة على التجزئة.والعمل على التجزئة.هذه هي أوجه التشابه بين HashMap وHashTable.
- ما الفرق بين HashMap و HashTable؟
1) الفرق الأول هو أن HashMap ليس آمنًا لمؤشر الترابط بينما HashTable هو ThreadSafe
2) أداء HashMap أفضل لأنه ليس آمنًا.في حين أن أداء Hashtable ليس أفضل لأنه آمن للخيط.لذلك لا يمكن لمؤشرات ترابط متعددة الوصول إلى Hashtable في نفس الوقت.
خريطة التجزئة:إنها فئة متاحة داخل حزمة java.util ويتم استخدامها لتخزين العنصر بتنسيق المفتاح والقيمة.
جدول التجزئة:إنها فئة قديمة يتم التعرف عليها داخل إطار عمل المجموعة.
Hashtable:
جدول التجزئة عبارة عن بنية بيانات تحتفظ بقيم زوج القيمة الرئيسية.لا يسمح بالقيمة الفارغة لكل من المفاتيح والقيم.سوف تحصل على NullPointerException
إذا قمت بإضافة قيمة فارغة.تتم مزامنتها.لذلك يأتي مع تكلفته.يمكن الوصول إلى موضوع واحد فقط HashTable في وقت معين.
مثال :
import java.util.Map;
import java.util.Hashtable;
public class TestClass {
public static void main(String args[ ]) {
Map<Integer,String> states= new Hashtable<Integer,String>();
states.put(1, "INDIA");
states.put(2, "USA");
states.put(3, null); //will throw NullPointerEcxeption at runtime
System.out.println(states.get(1));
System.out.println(states.get(2));
// System.out.println(states.get(3));
}
}
خريطة التجزئة:
خريطة التجزئة يشبه جدول التجزئة ولكنه يقبل أيضًا زوج القيمة الرئيسية.يسمح بـ null لكل من المفاتيح والقيم.أدائها أفضل من أفضل HashTable
, لأنه كذلك unsynchronized
.
مثال:
import java.util.HashMap;
import java.util.Map;
public class TestClass {
public static void main(String args[ ]) {
Map<Integer,String> states = new HashMap<Integer,String>();
states.put(1, "INDIA");
states.put(2, "USA");
states.put(3, null); // Okay
states.put(null,"UK");
System.out.println(states.get(1));
System.out.println(states.get(2));
System.out.println(states.get(3));
}
}
يمنحك HashMaps حرية المزامنة وتصحيح الأخطاء أسهل بكثير
HashMap
تمت محاكاته وبالتالي يمكن استخدامه في GWT client code
بينما Hashtable
ليس.
المزامنة أو الخيط الآمن :
لا تتم مزامنة Hash Map وبالتالي فهي ليست آمنة للترابط ولا يمكن مشاركتها بين سلاسل رسائل متعددة بدون كتلة متزامنة مناسبة بينما تتم مزامنة Hashtable وبالتالي فهي آمنة للخيط.
المفاتيح الخالية والقيم الخالية :
يسمح HashMap بمفتاح فارغ واحد وأي عدد من القيم الخالية. لا يسمح Hashtable بالمفاتيح أو القيم الخالية.
تكرار القيم:
التكرار في HashMap هو مكرر سريع الفشل بينما العداد الخاص بـ Hashtable ليس كذلك ويطرح ConcurrentModificationException إذا قام أي مؤشر ترابط آخر بتعديل الخريطة هيكليًا عن طريق إضافة أو إزالة أي عنصر باستثناء طريقة الإزالة () الخاصة بـ Iterator.
الطبقة المتفوقة والإرث :
HashMap هي فئة فرعية من فئة AbstractMap بينما Hashtable هي فئة فرعية من فئة القاموس.
أداء :
نظرًا لأن HashMap غير متزامن، فهو أسرع مقارنةً بـ Hashtable.
يشير إلى http://modernpathshala.com/Article/1020/difference-between-hashmap-and-hashtable-in-Java للحصول على أمثلة وأسئلة المقابلة والاختبار المتعلق بمجموعة Java