מבוא ל- StreamEx

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

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

StreamEx היא ספרייה המספקת פונקציונליות נוספת עבור ה- API של Stream סטנדרטי יחד עם שיפורי הביצועים.

להלן מספר תכונות עיקריות:

  • דרכים קצרות ונוחות יותר לבצע את המשימות היומיומיות
  • תאימות של 100% ל- JDK המקורי זרמים
  • ידידותיות לעיבוד מקביל: כל פיצ'ר חדש מנצל את היתרון בזרמים מקבילים ככל האפשר
  • ביצועים ותקורה מינימלית. אם StreamEx מאפשרת לפתור את המשימה באמצעות פחות קוד בהשוואה לתקן זרם, זה לא אמור להיות איטי משמעותית מהדרך הרגילה (ולפעמים זה אפילו מהיר יותר)

במדריך זה נציג כמה מהתכונות של StreamEx ממשק API.

2. הגדרת הדוגמא

להשתמש StreamEx, עלינו להוסיף את התלות הבאה ל- pom.xml:

 one.util streamex 0.6.5 

את הגרסה האחרונה של הספרייה תוכלו למצוא ב- Maven Central.

באמצעות הדרכה זו נשתמש בפשטות מִשׁתַמֵשׁ מעמד:

משתמש בכיתה ציבורית {id id; שם מחרוזת; תפקיד תפקיד = תפקיד חדש (); // סטנדרטים, סטרים ובונים סטנדרטיים}

ופשוט תַפְקִיד מעמד:

תפקיד בכיתה ציבורית {}

3. שיטות קיצור דרך אספנים

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

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

users.stream () .map (משתמש :: getName) .collect (Collectors.toList ());

3.1. איסוף לאוסף

עכשיו, עם StreamEx, אנחנו לא צריכים לספק אַסְפָן כדי לציין שאנחנו צריכים a רשימה, הגדר, מפה, InmutableList, וכו.:

רשימת userNames = StreamEx.of (משתמשים) .map (משתמש :: getName) .toList ();

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

3.2. אספנים מתקדמים

קצרנות נוספת היא קיבוץ לפי:

מַפָּה role2users = StreamEx.of (משתמשים) .groupingBy (משתמש :: getRole);

זה יפיק א מַפָּה עם סוג המפתח שצוין בהפניה לשיטה, ומייצר משהו דומה לקבוצה על ידי פעולה ב- SQL.

באמצעות רגיל זרם API, נצטרך לכתוב:

מַפָּה role2users = users.stream () .collect (Collectors.groupingBy (משתמש :: getRole));

ניתן למצוא טופס קצרנות דומה עבור ה- Collectors.joining ():

StreamEx.of (1, 2, 3) .joining (";"); // "1; 2; 3"

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

4. הוספה, הסרה ובחירת אלמנטים

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

רשימת usersAndRoles = Arrays.asList (משתמש חדש (), תפקיד חדש ()); תפקידי רשימה = StreamEx.of (usersAndRoles). בחר (Role.class) .toList ();

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

רשימה appendedUsers = StreamEx.of (משתמשים) .map (משתמש :: getName) .prepend ("(none)") .append ("LAST") .toList ();

אנו יכולים להסיר אלמנטים null לא רצויים באמצעות nonNull () והשתמש ב- זרם כמו ניתן לנידון:

עבור (קו מחרוזת: StreamEx.of (משתמשים) .map (משתמש :: getName) .nonNull ()) {System.out.println (שורה); }

5. פעולות מתמטיקה ותמיכה בסוגים פרימיטיביים

StreamEx מוסיף תומכים לסוגים פרימיטיביים, כפי שאנו יכולים לראות בדוגמה המסבירה את עצמה:

קצר [] src = {1,2,3}; char [] output = IntStreamEx.of (src) .map (x -> x * 5) .toCharArray ();

עכשיו בואו ניקח מערך של לְהַכפִּיל אלמנטים בצורה לא מסודרת. אנו רוצים ליצור מערך המורכב מההבדל בין כל זוג.

אנחנו יכולים להשתמש ב- pairMap שיטה לביצוע פעולה זו:

כפול ציבורי [] getDiffBetweenPairs (כפול ... מספרים) {החזר DoubleStreamEx.of (numbers) .pairMap ((a, b) -> b - a) .toArray (); }

6. פעולות מפה

6.1. סינון לפי מפתחות

תכונה שימושית נוספת היא יכולת ליצור a זרם מ מַפָּה וסנן את האלמנטים באמצעות הערכים שהם מצביעים עליהם.

במקרה זה אנו לוקחים את כל הערכים שאינם null:

Map nameToRole = HashMap חדש (); nameToRole.put ("ראשון", תפקיד חדש ()); nameToRole.put ("שנייה", null); הגדר nonNullRoles = StreamEx.ofKeys (nameToRole, אובייקטים :: nonNull) .toSet ();

6.2. פועל על זוגות ערך מפתח

אנו יכולים גם לפעול על צמדי ערך מפתח על ידי יצירת EntryStream למשל:

מפה ציבורית transformMap (מפה role2users) {מפה users2roles = EntryStream.of (role2users) .flatMapValues ​​(List :: stream) .invert () .grouping (); להחזיר users2roles; }

המבצע המיוחד EntryStream.of לוקח מַפָּה והופך אותו לא זרם של אובייקטים בעלי ערך מפתח. ואז אנחנו משתמשים flatMapValues פעולה כדי להפוך את רשימת התפקידים שלנו ל- זרם של ערכים בודדים.

הבא, אנחנו יכולים לַהֲפוֹך צמד ערכי המפתח, מה שהופך את מִשׁתַמֵשׁ מחלק את המפתח ואת תַפְקִיד מחלק את הערך.

ולבסוף, אנו יכולים להשתמש ב- הַקבָּצָה פעולה להפוך את המפה שלנו להיפוך של זו שהתקבלה, והכל עם ארבע פעולות בלבד.

6.3. מיפוי ערך-מפתח

אנו יכולים גם למפות מפתחות וערכים באופן עצמאי:

מפה mapToString = EntryStream.of (users2roles) .mapKeys (String :: valueOf) .mapValues ​​(String :: valueOf) .toMap ();

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

7. פעולות קבצים

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

StreamEx.ofLines (reader) .remove (String :: isEmpty) .forEach (System.out :: println);

שים לב שהשתמשנו לְהַסִיר() שיטה לסינון קווים ריקים.

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

8. מסקנה

במדריך זה למדנו על StreamExוזה כלי עזר שונה. יש עוד המון מה לעבור - ויש להם כאן גיליון בגידות שימושי.

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


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