سؤال

ما هي الاختلافات بين أ HashMap و أ Hashtable في جافا؟

ما هو أكثر كفاءة للتطبيقات غير مترابطة؟

هل كانت مفيدة؟

المحلول

هناك عدة اختلافات بين HashMap و Hashtable في جافا:

  1. Hashtable يكون متزامن, ، بينما HashMap ليس.هذا يجعل HashMap أفضل للتطبيقات غير المترابطة، حيث أن الكائنات غير المتزامنة عادةً ما تكون أفضل من تلك المتزامنة.

  2. Hashtable لا يسمح null المفاتيح أو القيم. HashMap يسمح لأحد null المفتاح وأي عدد من null قيم.

  3. إحدى الفئات الفرعية لـ 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.

غالبًا ما يتم طرح هذا السؤال في المقابلة للتحقق مما إذا كان المرشح يفهم الاستخدام الصحيح لفئات التحصيل وعلى دراية بالحلول البديلة المتاحة.

  1. فئة HashMap تعادل تقريبًا Hashtable، باستثناء أنها غير متزامنة وتسمح بالقيم الخالية.(يسمح HashMap بالقيم الخالية كمفتاح وقيمة بينما لا يسمح Hashtable بالقيم الخالية).
  2. لا يضمن HashMap بقاء ترتيب الخريطة ثابتًا بمرور الوقت.
  3. HashMap غير متزامن بينما تتم مزامنة Hashtable.
  4. يعتبر التكرار في HashMap آمنًا من الفشل بينما العداد الخاص بـ Hashtable ليس كذلك ويرمي ConcurrentModificationException إذا قام أي مؤشر ترابط آخر بتعديل الخريطة هيكليًا عن طريق إضافة أو إزالة أي عنصر باستثناء طريقة الإزالة () الخاصة بـ Iterator.لكن هذا ليس سلوكًا مضمونًا وسيتم تنفيذه بواسطة JVM بأقصى جهد.

ملاحظة على بعض الشروط الهامة

  1. المزامنة تعني أن مؤشر ترابط واحد فقط يمكنه تعديل جدول التجزئة في وقت واحد.في الأساس، هذا يعني أن أي مؤشر ترابط قبل إجراء تحديث على جدول التجزئة سيتعين عليه الحصول على قفل على الكائن بينما سينتظر الآخرون حتى يتم تحرير القفل.
  2. تعتبر الحماية من الفشل ذات صلة بسياق التكرارات.إذا تم إنشاء مكرر على كائن مجموعة وحاول مؤشر ترابط آخر تعديل كائن المجموعة "بنيويًا"، فسيتم طرح استثناء التعديل المتزامن.من الممكن أن تستدعي سلاسل الرسائل الأخرى طريقة "set" لأنها لا تقوم بتعديل المجموعة "هيكليًا".ومع ذلك، إذا تم تعديل المجموعة هيكليًا قبل استدعاء "set"، فسيتم طرح "IllegalArgumentException".
  3. التعديل الهيكلي يعني حذف أو إدراج عنصر يمكن أن يغير بنية الخريطة بشكل فعال.

يمكن مزامنة 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.

enter image description here

وبالإضافة إلى ما قاله عزب، HashMap يسمح بالقيم الخالية، في حين أن Hashtable لا.

لاحظ ذلك أيضًا Hashtable يمتد Dictionary الطبقة، والتي كما جافادوكس الدولة، عفا عليها الزمن وتم استبدالها بـ Map واجهه المستخدم.

هناك العديد من الإجابات الجيدة التي تم نشرها بالفعل.أقوم بإضافة بعض النقاط الجديدة وتلخيصها.

HashMap و Hashtable كلاهما يستخدم للتخزين البيانات في شكل المفتاح والقيمة.كلاهما يستخدم تقنية التجزئة لتخزين المفاتيح الفريدة.ولكن هناك العديد من الاختلافات بين فئات HashMap وHashtable الموضحة أدناه.

خريطة التجزئة

  1. HashMap غير متزامن.إنه ليس آمنًا للخيوط ولا يمكن مشاركته بين العديد من سلاسل الرسائل دون رمز المزامنة المناسب.
  2. HashMap يسمح بمفتاح فارغ واحد وقيم فارغة متعددة.
  3. HashMap هي فئة جديدة تم تقديمها في JDK 1.2.
  4. HashMap سريع.
  5. يمكننا أن نجعل HashMap كما تمت مزامنته عن طريق استدعاء هذا الرمز
    Map m = Collections.synchronizedMap(HashMap);
  6. HashMap تم اجتيازه بواسطة Iterator.
  7. مكرر في HashMap سريع الفشل.
  8. HashMap يرث فئة AbstractMap.

جدول التجزئة

  1. Hashtable تتم مزامنة.إنه آمن للخيوط ويمكن مشاركته مع العديد من المواضيع.
  2. Hashtable لا يسمح بأي مفتاح أو قيمة فارغة.
  3. Hashtable هي فئة تراث.
  4. Hashtable بطيء.
  5. Hashtable متزامن داخليًا ولا يمكن إلغاء مزامنته.
  6. Hashtable يتم اجتيازها بواسطة Enumerator و Iterator.
  7. العداد في Hashtable ليس سريع الفشل.
  8. Hashtable يرث فئة القاموس.

قراءة متعمقة ما الفرق بين HashMap و Hashtable في Java؟

enter image description here

نلقي نظرة على هذا الرسم البياني.يوفر مقارنات بين هياكل البيانات المختلفة إلى جانب 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...:(

هل ستكون تحسينات مجموعة Project Coin موجودة في JDK8؟

  • 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 { ... }

« السعة الأولية وعامل الحمولة

السعة هي عدد الدلاء في جدول التجزئة، والقدرة الأولية هي ببساطة السعة في وقت إنشاء جدول التجزئة.لاحظ أن جدول التجزئة مفتوح:في حالة "hashcollision"، يقوم دلو واحد بتخزين إدخالات متعددة، والتي يجب البحث عنها بشكل تسلسلي.عامل التحميل هو مقياس لمدى امتلاء جدول التجزئة قبل زيادة سعته تلقائيًا.

يقوم HashMap بإنشاء جدول تجزئة فارغ بالسعة الأولية الافتراضية (16) وعامل الحمولة الافتراضي (0.75).حيث يقوم Hashtable بإنشاء جدول تجزئة فارغ بسعة أولية افتراضية (11) وعامل الحمولة/نسبة الملء (0.75).

Hash Map & Hashtable

« التعديل الهيكلي في حالة تصادم التجزئة

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.

  1. تتيح لك الخرائط تكرار واسترداد المفاتيح والقيم وأزواج القيمة الرئيسية أيضًا، حيث لا يتمتع HashTable بكل هذه الإمكانية.
  2. يوجد في Hashtable وظيفة تحتوي على () وهي مربكة جدًا للاستخدام.لأن معنى يحتوي انحراف طفيف.هل يعني أنه يحتوي على مفتاح أو يحتوي على قيمة؟من الصعب أن نفهم.نفس الشيء في الخرائط لدينا وظائف يحتوي على مفتاح () ويحتوي على قيمة ()، والتي من السهل جدًا فهمها.
  3. في hashmap، يمكنك إزالة العنصر أثناء التكرار بأمان.حيث أنه ليس من الممكن في hashtables.
  4. تتم مزامنة HashTables بشكل افتراضي، لذلك يمكن استخدامها مع سلاسل رسائل متعددة بسهولة.حيث لا تتم مزامنة HashMaps افتراضيًا، لذلك يمكن استخدامها مع مؤشر ترابط واحد فقط.ولكن لا يزال بإمكانك تحويل HashMap إلى متزامن باستخدام وظيفة SynchronizedMap(Map m) الخاصة بفئة Collections util.
  5. لن يسمح HashTable بالمفاتيح الخالية أو القيم الخالية.حيث يسمح HashMap بمفتاح فارغ واحد وقيم فارغة متعددة.

مشاركتي البسيطة :

  1. الفرق الأول والأهم بين Hashtable و HashMap هل هذا، HashMap ليست آمنة للخيط في حين Hashtable هي مجموعة آمنة للخيط.

  2. الفرق الثاني المهم بين Hashtable و HashMap هو الأداء، منذ ذلك الحين HashMap غير متزامنة أداء أفضل من Hashtable.

  3. الفرق الثالث على 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

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top