השוואת HashSet ו- TreeSet

1. הקדמה

במאמר זה, נשווה שניים מיישומי Java הפופולריים ביותר של java.util.Set ממשק - HashSet ו TreeSet.

2. הבדלים

HashSet ו TreeSet הם עלים של אותו ענף, אך הם נבדלים בכמה עניינים חשובים.

2.1. מזמין

HashSet מאחסן את האובייקטים בסדר אקראי, ואילו TreeSet מיישם את הסדר הטבעי של היסודות. בואו נראה את הדוגמה הבאה:

@Test הציבורי בטל givenTreeSet_whenRetrievesObjects_thenNaturalOrder () {Set set = new TreeSet (); set.add ("באלדונג"); set.add ("זה"); set.add ("מדהים"); assertEquals (3, set.size ()); assertTrue (set.iterator (). הבא (). שווה ("מדהים")); }

לאחר הוספת ה- חוּט חפצים לתוך TreeSet, אנו רואים שהראשון הוא "מדהים", למרות שהוא נוסף בסוף. פעולה דומה שנעשתה עם HashSet אינו מתחייב שסדר האלמנטים יישאר קבוע לאורך זמן.

2.2. ריק חפצים

הבדל נוסף הוא בכך HashSet יכול לאחסן ריק חפצים, ואילו TreeSet אינו מאפשר להם:

@Test (צפוי = NullPointerException.class) חלל ציבורי givenTreeSet_whenAddNullObject_thenNullPointer () {Set set = new TreeSet (); set.add ("באלדונג"); set.add ("זה"); set.add (null); } @Test ציבורי בטל givenHashSet_whenAddNullObject_thenOK () {Set set = חדש HashSet (); set.add ("באלדונג"); set.add ("זה"); set.add (null); assertEquals (3, set.size ()); }

אם ננסה לאחסן את ריק חפץ בא TreeSet, הפעולה תביא לזריקה NullPointerException. היוצא מן הכלל היחיד היה בג'אווה 7 כאשר הורשה שיהיה לו אחד כזה ריק אלמנט ב TreeSet.

2.3. ביצועים

פשוט שים, HashSet מהיר יותר מה- TreeSet.

HashSet מספק ביצועים בזמן קבוע לרוב הפעולות כמו לְהוֹסִיף(), לְהַסִיר() ו מכיל (), לעומת עֵץ(נ) הזמן המוצע על ידי TreeSet.

בדרך כלל אנו יכולים לראות זאת זמן הביצוע להוספת אלמנטים לתוך TreeSet הוא הרבה יותר טוב מאשר עבור HashSet.

אנא זכור כי ה- JVM לא יכול להיות מחומם, כך שזמני הביצוע עשויים להיות שונים. דיון טוב כיצד לתכנן ולבצע בדיקות מיקרו באמצעות שונות מַעֲרֶכֶת יישומים זמינים כאן.

2.4. שיטות מיושמות

TreeSet עשיר בפונקציות, יישום שיטות נוספות כמו:

  • pollFirst () - להחזרת האלמנט הראשון, או ריק אם מַעֲרֶכֶת זה ריק
  • pollLast () - כדי לאחזר ולהסיר את האלמנט האחרון, או להחזיר ריק אם מַעֲרֶכֶת זה ריק
  • ראשון() - להחזרת הפריט הראשון
  • אחרון()להחזרת הפריט האחרון
  • תִקרָה() - להחזיר את האלמנט הכי פחות גדול או שווה לאלמנט הנתון, או ריק אם אין אלמנט כזה
  • נמוך יותר() - להחזיר את האלמנט הגדול פחות מהאלמנט הנתון, או ריק אם אין אלמנט כזה

השיטות שהוזכרו לעיל יוצרות TreeSet הרבה יותר קל לשימוש וחזק יותר מ HashSet.

3. קווי דמיון

3.1. אלמנטים ייחודיים

שניהם TreeSet ו HashSet להבטיח א אוסף אלמנטים ללא שכפול, כיוון שהוא חלק מהגנרי מַעֲרֶכֶת מִמְשָׁק:

@Test ציבורי בטל givenHashSetAndTreeSet_whenAddDuplicates_thenOnlyUnique () {Set set = חדש HashSet (); set.add ("באלדונג"); set.add ("באלדונג"); assertTrue (set.size () == 1); הגדר set2 = TreeSet חדש (); set2.add ("באלדונג"); set2.add ("באלדונג"); assertTrue (set2.size () == 1); }

3.2. לֹא מסונכרן

אף אחד מהמתוארים מַעֲרֶכֶת יישומים הם מסונכרן. המשמעות היא שאם מספר אשכולות ניגשים אל מַעֲרֶכֶת במקביל, ולפחות אחד מהשרשורים משנה אותו, אז עליו להיות מסונכרן חיצונית.

3.3. איטרטורים מהירים

ה איטרטורחזרו על ידי TreeSet ו HashSet הם מהירים.

פירוש הדבר שכל שינוי של ה- מַעֲרֶכֶת בכל עת לאחר איטרטור נוצר יזרוק א ConcurrentModificationException:

@Test (צפוי = ConcurrentModificationException.class) חלל ציבורי givenHashSet_whenModifyWhenIterator_thenFailFast () {Set set = חדש HashSet (); set.add ("באלדונג"); Iterator it = set.iterator (); בעוד (it.hasNext ()) {set.add ("מדהים"); it.next (); }}

4. באיזה מימוש להשתמש?

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

להלן מספר נקודות מהירות שיש לזכור:

  • אם אנו רוצים לשמור על ערכינו מסודרים, עלינו ללכת על TreeSet
  • אם אנו מעריכים ביצועים יותר מצריכת זיכרון, עלינו ללכת על HashSet
  • אם חסר לנו הזיכרון, עלינו ללכת על TreeSet
  • אם אנו רוצים לגשת לאלמנטים שקרובים יחסית זה לזה על פי הסדר הטבעי שלהם, כדאי לנו לשקול TreeSet כי יש לו יותר יישוב
  • HashSetניתן לכוון את הביצועים באמצעות initialCapacity ו loadFactor, אשר אינו אפשרי עבור ה- TreeSet
  • אם אנו רוצים לשמור על צו הכניסה וליהנות מגישה קבועה לזמן, אנו יכולים להשתמש ב- LinkedHashSet

5. מסקנה

במאמר זה סקרנו את ההבדלים והדמיון בין TreeSet ו HashSet.

כמו תמיד, דוגמאות הקוד למאמר זה זמינות ב- GitHub.


$config[zx-auto] not found$config[zx-overlay] not found