JavaRush /בלוג Java /Random-HE /אתחול סד כפול
Joysi
רָמָה

אתחול סד כפול

פורסם בקבוצה

1. אתחול סד כפול

אתחול באמצעות סוגרים כפולים ( להלן כפולים כפולים ) הוא כלי ג'אווה ליצירת אוספים כגון רשימה, סט ומפה בו-זמנית עם ההצהרה שלהם.
אתחול סד כפול - 1
כאשר אתה צריך רשימות עם אלמנטים קבועים, כגון רשימה של מוצרים או מטבעות נתמכים, הצהרת הרשימה במקביל לאתחול שלה משפרת את קריאות הקוד. זו הסיבה שאתחול Double brace צובר פופולריות, מכיוון שאין שיטות סטנדרטיות אחרות ליצירת אוספים עם אתחול סימולטני בקוד. למרבה הצער, בניגוד לשפות תכנות אחרות, Java אינה תומכת באוספים של מילים. בשל מגבלה זו, יצירת רשימה בלתי ניתנת לשינוי אפילו עם מספר קטן של אלמנטים מאלצת אותנו לכתוב שורות קוד רבות בצורה של קריאות חוזרות ונשנות add()כדי להוסיף את האלמנטים הרצויים עם גלישה סופית:
List<Integer> list = new ArrayList<>();
list.add(2);
list.add(3);
list.add(5);
list.add(7);
List<Integer> unmodifiableList = Collections.unmodifiableList(list);
זהו תיאור מיותר שלא לצורך שניתן לפשט אותו. בואו נמלא רשימות סטטיות בצורה נוחה לנו, כלומר ישירות בבלוקים סטטיים בזמן האתחול, ובזה Double braceהאתחול יעזור לנו, ויאפשר לנו לכתוב הכל בשורה אחת:
List<Integer> list = Collections.unmodifiableList(new ArrayList<Integer>() {{
        add(2);
        add(3);
        add(5);
}});
באופן דומה, Double braceאתחול יעזור לנו למלא ערכים ו HashMap:
Map<Integer, String> intToString = new HashMap<Integer, String>(){{
         put(1, "one");
         put(2, "two");
         put(3, "three");
 }};
הכל נראה כל כך אלגנטי, אבל יש לו חסרונות, שהופכים את אתחול הפלטה הכפולה לאנטי-דפוס. נסתכל עליהם עוד יותר בפרק הבא.

יתרונות וחסרונות של אתחול סד כפול.

Doubleאתחול סד משתמש ביצירת מחלקה פנימית אנונימית . עם זאת, מה שמוסתר בתחילה על פני השטח, Double braceהאתחול יוצר מחלקה עם אתחול נוסף של המופע שלו בכל פעם שאתה משתמש בו. בנוסף, נעשה שימוש בהתייחסות נסתרת לשיעור פרטי זה, שיכול להוביל אותנו לדליפות זיכרון אפשריות. אתה גם לא יכול להשתמש באופרטור הרפאים לגנריות (אופרטור יהלומים < >), מכיוון שאיננו יכולים לגשת לחלק הפנימי של מחלקה אנונימית.
(מהמתרגם: שוב בפירוט רב יותר:
לאחר הראשון {נוצרת מחלקה אנונימית פנימית, לאחר השנייה {מתרחשת אתחול בעת יצירת מופע של המחלקה, בו יש לנו גישה לשדות ולשיטות של החיצוני ( יחסית לכיתה האנונימית).
יתרונות:
  1. הקטנת שורות בקוד
  2. יצירה ואתחול בביטוי אחד.
מינוסים:
  1. יצירת כיתה אנונימית מוסתרת ממך.
  2. מה שעולה לנו עלויות נוספות עבור המופע שלו בכל פעם שאנו משתמשים בו.
  3. בכל פעם נוצרת התייחסות נסתרת אליו, שעלולה להוביל לדליפות זיכרון.
פסק דין: בשל החסרונות לעיל וקיומן של חלופות ל-Double brace, האתחול נתפס כאנטי-דפוס בעולם הג'אווה. הצילו את החתלתול

חלופות לאתחול כפול סד ב-Java

החדשות הטובות הן שיש דרכים אחרות להשיג את אותן מטרות בג'אווה. אנו יכולים ליישם בשורת קוד אחת את היצירה והאתחול של ArrayList באמצעות הבנאי Copy מהמחלקה Collection כפי שמוצג להלן:
List<Integer> list = Collections.unmodifiableList(new ArrayList<>(Arrays.asList(2, 3, 5)));
Arrays.asList()יחזיר לנו רשימה באורך קבוע שהועבר לבנאי ArrayListההעתקה. זכור את ההבדל בין רשימות באורך קבוע המוחזרות מ- Arrays.asList()ו Collections.unmodifiableList(): אינך יכול להוסיף או להסיר אלמנטים ArrayListשל - , אך אתה יכול לשנות אלמנט לפי אינדקס באמצעות set(), מה שלא תוכל לעשות עם רשימה המוחזרת על ידי Collections.unmodifiableList(). אם אתה רוצה לקבל רשימה קטנה, זו הדרך הטובה ביותר, למרות שהיא תהיה פחות שקופה עבור Setאוספים אחרים, אז תצטרך ליצור אותה Listלפני יצירת Set-a. אבל זה עדיין עדיף על אתחול Double brace, מכיוון שבמקרה זה לא נוצרת מחלקה אנונימית פנימית נוספת בכל פעם שמשתמשים בה. אם אתה מריץ Java 8 יש לך שיטה חלופית אחרת. ה-API של JDK 8 Stream יעזור לך ליצור אוספים קטנים על ידי שילוב Stream Factoryשיטות פלט לאוסף List:
List<String> list = Collections.unmodifiableList(Stream.of("abc", "bcd", "cde").collect(toList()));
שכן Setאתה יכול להשתמש Collectors.toSet()בשיטה במקום Collectors.toList()כמו להלן:
Set<String> set = Collections.unmodifiableSet(Stream.of("abc", "bcd", "cde").collect(toSet()));
אגב, Stream collectהשיטות לא מבטיחות שהאוספים שהן מייצרות מוגנים מפני שינויים. ב-Java 8, האוספים שהם החזירו (כגון - ArrayList, HashSet, ו- HashMap) נפוצים למדי (נוכל לשנות אותם), אך ייתכן שעובדה זו תתוקן במהדורות עתידיות של JDK. זה הכל לעת עתה לגבי Double braceאתחול ב-Java. תבנית זו מקובלת לבדיקות והדגמות, אך אינה טובה מספיק לשימוש בייצור. בשל החסרונות הטבועים בו, אתחול ה-Double brace הפך לאנטי-דפוס בימינו, במיוחד לאור החלופות הקיימות. אני עצמי עדיין משתמש בבנייה הזו כדי לאתחל מפות סטטיות וזהו. שכן Listאני מעדיף ליצור Collectionsעל ידי שילוב עם יצירה Array.asListבקונסטרוקטור שלו. ואם אני משתמש ב-Java 8 - עיצוב באמצעות ה- Stream API ו- collect(). מאמרים קשורים: אם נהנית ממדריך זה וברצונך ללמוד עוד על דפוסי תכנות, עקרונות ושיטות עבודה מומלצות של Java, ייתכן שתרצה גם לעיין במאמרים האחרים באתר שלנו . קריאה מומלצת: אם אתה רוצה ללמוד עוד על דפוסים ושיטות עבודה מומלצות, עליך לקרוא תכנות אפקטיבי מאת ג'ושוע בלוך , שום ספר לא יכול לתפוס את מקומו. ואם אתם כבר בקיאים בג'אווה ומחפשים ספר על דפוסי עיצוב, שסגנון ההצגה ההומוריסטי שלו מעניין וקל לקריאה, שימו לב ל"ראש ראשון. תבניות עיצוב" .
מהמתרגם: בכוונה סיפקתי קישור לספרו המקורי של בלוך, מכיוון שתרגומו לרוסית לא מוצלח (לדוגמה, Builder = constructor).
תרגום המאמר מהי אתחול Double Brace ב-Java? דוגמה נגד תבנית (פורסם באוקטובר 2015).
הערות
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION