ההבדלים בין HashMap ל- Hashtable

1. סקירה כללית

במדריך קצר זה, אנו הולכים להתמקד בהבדלי הליבה בין טבלת גיבוב וה מפת גיבוב.

2. טבלת גיבוב ו מפת גיבוב בג'אווה

טבלת גיבוב ו מפת גיבוב דומים למדי - שניהם אוספים המיישמים את מַפָּה מִמְשָׁק.

וגם ה לָשִׂים(), לקבל(), לְהַסִיר(), ו containKey () שיטות מספקות ביצוע בזמן קבוע O (1). באופן פנימי, שיטות אלה פועלות על בסיס תפיסה כללית של hashing באמצעות דליים לאחסון נתונים.

אף מעמד לא שומר על סדר ההכנסה של האלמנטים. במילים אחרות, ייתכן שהפריט הראשון שנוסף אינו הפריט הראשון כאשר אנו חוזרים על הערכים.

אבל יש להם גם כמה הבדלים שהופכים אחד טוב יותר מאחר במצבים מסוימים. בואו נסתכל מקרוב על ההבדלים הללו.

3. ההבדלים בין טבלת גיבוב ו מפת גיבוב

3.1. סִנכְּרוּן

קוֹדֶם כֹּל, טבלת גיבוב הוא בטוח בחוטים וניתן לשתף אותו בין מספר שרשורים ביישום.

מצד שני, מפת גיבוב אינו מסונכרן ולא ניתן לגשת אליו באמצעות מספר שרשורים ללא קוד סנכרון נוסף. אנחנו יכולים להשתמש Collections.synchronizedMap () כדי ליצור גרסה בטוחה לשרשור מפת גיבוב. אנחנו יכולים גם פשוט ליצור קוד נעילה מותאם אישית או להפוך את קוד החוט לבטוח באמצעות מסונכרן מילת מפתח.

מפת גיבוב אינו מסונכרן, ולכן הוא מהיר יותר ומשתמש בפחות זיכרון מאשר טבלת גיבוב. באופן כללי, אובייקטים לא מסונכרנים מהירים יותר מאובייקטים מסונכרנים ביישום הברגה יחיד.

3.2. ערכים אפסיים

הבדל נוסף הוא ריק טיפול. מפת גיבוב מאפשר להוסיף אחד כְּנִיסָה עם ריק כמפתח כמו גם ערכים רבים עם ריק כערך. בניגוד, טבלת גיבוב לא מאפשר ריק בכלל. בואו נראה דוגמה ל ריק ו מפת גיבוב:

מפת HashMap = HashMap חדש (); map.put (null, "value"); map.put ("key1", null); map.put ("key2", null);

זה יביא ל:

assertEquals (3, map.size ());

לאחר מכן, בואו נראה כיצד Hashtable שונה:

שולחן Hashtable = Hashtable חדש (); table.put ("מפתח", null);

התוצאה היא א NullPointerException. הוספת אובייקט עם ריק כמפתח גורם גם לא NullPointerException:

table.put (null, "value");

3.3. איטרציה על אלמנטים

מפת גיבוב שימושים איטרטור לחזור על פני ערכים, ואילו טבלת גיבוב יש ל מונה לאותו דבר. ה איטרטור הוא יורש של מונה זה מבטל את החסרונות המועטים שלו. לדוגמה, איטרטור יש לְהַסִיר() שיטה להסרת אלמנטים מאוספים בסיסיים.

ה איטרטור הוא איטרטור מהיר להיכשל. במילים אחרות, זה זורק א ConcurrentModificationException כאשר האוסף הבסיסי משתנה תוך כדי איטרציה. בואו נראה את הדוגמה של כישלון מהיר:

מפת HashMap = HashMap חדש (); map.put ("key1", "value1"); map.put ("key2", "value2"); איטרטור איטרטור = map.keySet (). איטרטור (); ואילו (iterator.hasNext ()) {iterator.next (); map.put ("key4", "value4"); }

זה זורק א ConcurrentModificationException יוצא מן הכלל כי אנחנו מתקשרים לָשִׂים() תוך כדי איטרציה על האוסף.

4. מתי לבחור מפת גיבוב על טבלת גיבוב

עלינו להשתמש מפת גיבוב ליישום לא מסונכרן או עם הברגה יחידה.

ראוי להזכיר שמאז JDK 1.8, טבלת גיבוב הוצא משימוש. למרות זאת, ConcurrentHashMap זה נהדר טבלת גיבוב תַחֲלִיף. עלינו לשקול ConcurrentHashMap לשימוש ביישומים עם מספר אשכולות.

5. מסקנה

במאמר זה הדגמנו את ההבדלים בין מפת גיבוב ו טבלת גיבוב ומה צריך לזכור כשאנחנו צריכים לבחור אחד כזה.

כרגיל, היישום של כל הדוגמאות וקטעי הקוד הסתיים ב- Github.