מדריך EnumSet

1. הקדמה

במדריך זה נחקור את EnumSet אוסף מה java.util לארוז ולדון במוזרויות שלה.

ראשית נציג את התכונות העיקריות של הקולקציה ולאחר מכן נעבור על פנימיות הכיתה על מנת להבין את היתרונות שלה.

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

2. מה זה EnumSet

An EnumSet הוא מומחה מַעֲרֶכֶת אוסף לעבוד איתו enum שיעורים. זה מיישם את מַעֲרֶכֶת ממשק ומשתרע מ תקציר סט:

למרות ש תקציר סט ו תקציר אוסף לספק יישומים כמעט לכל השיטות של מַעֲרֶכֶת ו אוסף ממשקים, EnumSet עוקף את רובם.

כאשר אנו מתכננים להשתמש ב- EnumSet עלינו לקחת בחשבון כמה נקודות חשובות:

  • זה יכול להכיל רק enum ערכים וכל הערכים צריכים להיות שייכים לאותו דבר enum
  • זה לא מאפשר להוסיף ערכי null, זורק א NullPointerException בניסיון לעשות זאת
  • זה לא בטוח בחוטים, לכן עלינו לסנכרן אותו חיצוני במידת הצורך
  • האלמנטים מאוחסנים לפי הסדר שבו הם מוצהרים ב- enum
  • הוא משתמש באיטרטור שאינו בטוח כשל שעובד על עותק, כך שהוא לא זורק ConcurrentModificationException אם האוסף שונה כאשר הוא חוזר עליו

3. מדוע להשתמש EnumSet

ככלל אצבע, EnumSet תמיד צריך להיות מועדף על פני כל אחר מַעֲרֶכֶת יישום כאשר אנו מאחסנים enum ערכים.

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

3.1. פרטי היישום

EnumSet הוא פּוּמְבֵּיתַקצִיר מחלקה המכילה מספר שיטות מפעל סטטיות המאפשרות לנו ליצור מופעים. ה- JDK מספק 2 יישומים שונים - הם חבילה-פרטית ומגובה בקטור מעט:

  • RegularEnumSet ו
  • JumboEnumSet

RegularEnumSet משתמש בסינגל ארוך כדי לייצג את וקטור הסיביות. כל חלק מה- ארוך אלמנט מייצג ערך של enum. הערך ה- i של האנאום יאוחסן בסיבית ה- i-th, כך שקל למדי לדעת אם ערך קיים או לא. מאז ארוך הוא סוג נתונים של 64 סיביות, יישום זה יכול לאחסן עד 64 אלמנטים.

מצד שני, JumboEnumSet משתמש במערך של ארוך אלמנטים כקטור מעט.זה מאפשר ליישום זה לאחסן יותר מ -64 אלמנטים. זה עובד בערך כמו RegularEnumSet אך מבצעים כמה חישובים נוספים כדי למצוא את אינדקס המערך בו מאוחסן הערך.

באופן לא מפתיע, האלמנט הארוך הראשון במערך יאחסן את 64 הערכים הראשונים של ה- enum, האלמנט השני 64 הבא, וכן הלאה.

EnumSet שיטות המפעל יוצרות מקרים של יישום כזה או אחר בהתאם למספר האלמנטים של ה- enum:

אם (universe.length <= 64) להחזיר RegularEnumSet חדש (elementType, universe); אחרת תחזיר JumboEnumSet חדש (elementType, universe);

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

3.2. יתרונות משימוש ב- EnumSet

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

אם נשווה EnumSet עם אחר מַעֲרֶכֶת יישומים כמו HashSet, הראשון בדרך כלל מהיר יותר מכיוון שהערכים נשמרים בסדר צפוי וצריך לבחון רק ביט אחד לכל חישוב. בניגוד HashSetאין צורך לחשב את hashcode למצוא את הדלי הנכון.

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

4. פעולות עיקריות

רוב השיטות של EnumSet לעבוד כמו כל אחר מַעֲרֶכֶת, למעט השיטות ליצירת מופעים.

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

בדוגמאות שלנו נעבוד עם צֶבַעenum:

ציבור ציבורי {אדום, צהוב, ירוק, כחול, שחור, לבן}

4.1. שיטות יצירה

השיטות הפשוטות ביותר ליצור EnumSet הם כל() ו אף אחד מ(). בדרך זו אנו יכולים ליצור בקלות EnumSet המכיל את כל האלמנטים שלנו צֶבַע enum:

EnumSet.allOf (Color.class);

כמו כן, אנו יכולים להשתמש אף אחד מ() לעשות את ההפך וליצור אוסף ריק של צֶבַע:

EnumSet.noneOf (Color.class);

אם אנחנו רוצים ליצור EnumSet עם קבוצת משנה של ה- enum אלמנטים בהם אנו יכולים להשתמש בעומס יתר שֶׁל() שיטות. חשוב להבדיל בין השיטות עם מספר קבוע של פרמטרים עד 5 שונים לבין זה שמשתמש בו varargs:

Javadoc קובע כי הביצועים של varargs הגרסה יכולה להיות איטית יותר מהאחרות בגלל יצירת המערך. לכן, עלינו להשתמש בו רק אם ראשית עלינו להוסיף יותר מ -5 אלמנטים.

דרך נוספת ליצור קבוצת משנה של enum הוא באמצעות טווח() שיטה:

EnumSet.range (Color.YELLOW, Color.BLUE);

בדוגמה לעיל, EnumSet מכיל את כל האלמנטים מ צהוב ל כָּחוֹל. הם פועלים לפי הסדר שהוגדר ב enum:

[צהוב, ירוק, כחול]

שימו לב שהוא כולל את האלמנטים הראשונים והאחרונים שצוינו.

שיטת מפעל שימושית נוספת היא complementOf () המאפשר לנו לא לכלול את האלמנטים שעברו כפרמטרים. בואו ניצור EnumSet עם כל צֶבַע אלמנטים למעט שחור ולבן:

EnumSet.complementOf (EnumSet.of (Color.BLACK, Color.WHITE));

אם אנו מדפיסים אוסף זה אנו יכולים לראות שהוא מכיל את כל שאר האלמנטים:

[אדום, צהוב, ירוק, כחול]

סוף כל סוף, אנחנו יכולים ליצור EnumSet על ידי העתקת כל האלמנטים מאחר EnumSet:

EnumSet.copyOf (EnumSet.of (Color.BLACK, Color.WHITE));

באופן פנימי, זה מכנה שיבוט שיטה.

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

רשימת colorsList = ArrayList חדש (); colorList.add (Color.RED); EnumSet listCopy = EnumSet.copyOf (colorsList);

במקרה זה, listCopy מכיל רק את הצבע האדום.

4.2. פעולות אחרות

שאר הפעולות עובדות בדיוק כמו כל פעולה אחרת מַעֲרֶכֶת יישום ואין הבדל כיצד להשתמש בהם.

לכן, אנו יכולים ליצור ריק ריק EnumSet והוסף כמה אלמנטים:

EnumSet set = EnumSet.noneOf (Color.class); set.add (Color.RED); set.add (צבע.צהוב)

בדוק אם האוסף מכיל אלמנט ספציפי:

set.contains (Color.RED);

חזר על האלמנטים:

set.forEach (System.out :: println);

או פשוט הסר אלמנטים:

set.remove (Color.RED);

זאת, כמובן, בין כל שאר הפעולות שא מַעֲרֶכֶת תומך.

5. מסקנה

במאמר זה הראינו את התכונות העיקריות של EnumSet, היישום הפנימי שלה ואיך נוכל להפיק תועלת מהשימוש בו.

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

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


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