Java אופציונלי - orElse () לעומת orElseGet ()

1. הקדמה

ה- API של אופציונאלי בדרך כלל יש שתי שיטות העלולות לגרום לבלבול: אחרת() ו orElseGet ().

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

2. חתימות

ראשית נתחיל עם היסודות על ידי התבוננות בחתימותיהם:

T orElse ציבורי (T אחר) T orElseGet ציבורי (ספק אחר)

בְּבִירוּר, אחרת() לוקח כל פרמטר מסוג ט ואילו orElseGet () מקבל ממשק פונקציונלי מסוג ספק שמחזיר אובייקט מסוג ט.

עכשיו, בהתבסס על הג'אדוקים שלהם:

  • אחרת(): מחזיר את הערך אם קיים, אחרת מחזיר אַחֵר
  • orElseGet (): מחזיר את הערך אם קיים, אחרת הפעל אַחֵר ולהשיב את תוצאת קריאתו

3. הבדלים

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

3.1. אחרת()

בהנחה שהוגדר את הלוגר שלנו כהלכה, נתחיל בכתיבת פיסת קוד פשוטה:

שם מחרוזת = Optional.of ("baeldung") .orElse (getRandomName ());

שים לב ש getRandomName () היא שיטה המחזירה אקראי שֵׁם מ רשימהשֶׁל שמות:

מחרוזת ציבורית getRandomName () {LOG.info ("שיטת getRandomName () - התחל"); אקראי אקראי = אקראי חדש (); אינדקס int = random.nextInt (5); LOG.info ("שיטת getRandomName () - סוף"); להחזיר names.get (אינדקס); }

בעת ביצוע הקוד שלנו, נמצא להלן הודעות המודפסות במסוף:

שיטת getRandomName () - התחל שיטת getRandomName () - סוף

המשתנה שֵׁם יחזיק "באלדונג" בסוף ביצוע הקוד.

בעזרתו נוכל להסיק בקלות שה- פרמטר של אחרת() מוערך גם כשיש לא ריק אופציונאלי.

3.2. orElseGet ()

עכשיו, בואו ננסה לכתוב קוד דומה באמצעות orElseGet ():

שם מחרוזת = Optional.of ("baeldung") .orElseGet (() -> getRandomName ());

הקוד שלעיל לא יופעל getRandomName () שיטה.

זכור (מהג'אדוק) כי ה- Sעליון השיטה שהועברה כוויכוח מתבצעת רק כאשר אופציונלי ערך אינו קיים.

באמצעות orElseGet () כי המקרה שלנו יחסוך לנו אפוא זמן מה בחישוב אקראי שֵׁם.

4. מדידת השפעת הביצועים

עכשיו, כדי להבין גם את ההבדלים בביצועים, בואו נשתמש ב- JMH ונראה כמה מספרים בפועל:

@Benchmark @BenchmarkMode (Mode.AverageTime) מחרוזת ציבורית או ElseBenchmark () {return Optional.of ("baeldung"). OrElse (getRandomName ()); }

וגם orElseGet ():

@Benchmark @BenchmarkMode (Mode.AverageTime) מחרוזת ציבורית orElseGetBenchmark () {return Optional.of ("baeldung"). OrElseGet (() -> getRandomName ()); }

בעת ביצוע שיטות הביצוע שלנו, אנו מקבלים:

יחידות שגיאה במצב ציון Cnt ציון orElseBenchmark avgt 20 60934.425 ± 15115.599 ns / op orElseGetBenchmark avgt 20 3.798 ± 0.030 ns / op

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

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

אחרי הכל, אחרת() כולל חישוב של getRandomName () שיטה לכל ריצה.

5. מה חשוב?

מלבד היבטי הביצועים, גורמים אחרים שיש לקחת בחשבון כוללים:

  • מה אם השיטה תבצע הגיון נוסף? לְמָשָׁל. ביצוע הכנסות או עדכונים של DB
  • גם כשאנחנו מקצים אובייקט ל אחרת() פָּרָמֶטֶר:
    שם מחרוזת = Optional.of ("baeldung"). OrElse ("אחר")

    אנחנו עדיין יוצרים "אַחֵר" התנגד ללא סיבה

ולכן חשוב לנו לקבל החלטה מדוקדקת בקרב אחרת() ו orElseGet () בהתאם לצרכים שלנו - כברירת מחדל, הגיוני יותר להשתמש בו orElseGet () בכל פעם אלא אם כן אובייקט ברירת המחדל כבר בנוי ונגיש ישירות.

6. מסקנה

במאמר זה למדנו את הניואנסים בין אופציונלי orElse () ו OrElseGet () שיטות. שמנו לב גם שלפעמים למושגים כה פשוטים יכולה להיות משמעות עמוקה יותר.

כמו תמיד, ניתן למצוא את קוד המקור השלם ב- Github.


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