מבוא ל- jOOL

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

במאמר זה נבחן את ה- jOOLספרייה - מוצר נוסף מ- jOOQ.

2. תלות של Maven

נתחיל בהוספת תלות ב- Maven שלך pom.xml:

 org.jooq jool 0.9.12 

תוכל למצוא את הגרסה האחרונה כאן.

3. ממשקים פונקציונליים

ב- Java 8, ממשקים פונקציונליים מוגבלים למדי. הם מקבלים את המספר המרבי של שני פרמטרים ואין להם הרבה תכונות נוספות.

jOOL מתקן את זה על ידי הוכחת קבוצה של ממשקים פונקציונליים חדשים שיכולים לקבל אפילו 16 פרמטרים (מאת פונקציה 1 עד ל פונקציה 16) ומועשרים בשיטות שימושיות נוספות.

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

Function3 lengthSum = (v1, v2, v3) -> v1.length () + v2.length () + v3.length ();

בג'אווה טהורה תצטרך ליישם אותה בעצמך. חוץ מזה, לממשקים פונקציונליים מ- jOOL יש שיטה החל באופן חלקי () המאפשר לנו לבצע יישום חלקי בקלות:

פונקציה 2 addTwoNumbers = (v1, v2) -> v1 + v2; פונקציה 1 addToTwo = addTwoNumbers.applyPartially (2); תוצאה שלמה = addToTwo.apply (5); assertEquals (תוצאה, (מספר שלם) 7);

כשיש לנו שיטה שהיא של א פונקציה 2 אנו יכולים להפוך אותו בקלות לג'אווה רגילה BiFunction באמצעות א toBiFunction () שיטה:

BiFunction biFunc = addTwoNumbers.toBiFunction ();

באופן דומה, יש לתפקד() שיטה ב פונקציה 1 סוּג.

4. צמרות

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

הם גם מאוד שימושיים בעת ביצוע טרנספורמציות בזרם אירועים. ב- jOOL, יש לנו צינורות שיכולים לעטוף מאחד עד שש עשרה ערכים, המסופקים על ידי Tuple1 עד ל טופלה סוגים:

tuple (2, 2)

ולארבעה ערכים:

tuple (1,2,3,4); 

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

רצף personDetails = Seq.of (tuple ("michael", "similar", 49), tuple ("jodie", "משתנה", 43)); Tuple2 tuple = tuple ("חורף", "קיץ"); רשימה תוצאה = personDetails .map (t -> t.limit2 (). concat (tuple)). toList (); assertEquals (תוצאה, Arrays.asList (tuple ("מיכאל", "דומה", "חורף", "קיץ"), tuple ("jodie", "משתנה", "חורף", "קיץ")));

אנו יכולים להשתמש בסוגים שונים של טרנספורמציות על צמרות. ראשית, אנו קוראים a limit2 () שיטה לקחת רק שני ערכים מ Tuple3. ואז, אנו קוראים a concat () שיטה לשרשור שני צמרות.

בתוצאה, אנו מקבלים ערכים שהם של Tuple4 סוּג.

5. רצף

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

5.1. מכיל פעולות

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

assertTrue (Seq.of (1, 2, 3, 4) .contains (2)); assertTrue (Seq.of (1, 2, 3, 4) .containsAll (2, 3)); assertTrue (Seq.of (1, 2, 3, 4) .containsAny (2, 5)); 

5.2. הצטרף למבצעים

כשיש לנו שני זרמים ואנחנו רוצים להצטרף אליהם (בדומה לפעולת הצטרפות SQL של ​​שני מערכי נתונים), באמצעות תקן זרם הכיתה אינה דרך אלגנטית במיוחד לעשות זאת:

זרם שמאל = Stream.of (1, 2, 4); זרם ימינה = Stream.of (1, 2, 3); רשימה rightCollected = right.collect (Collectors.toList ()); רשימה collect = left .filter (rightCollected :: מכיל) .collect (Collectors.toList ()); assertEquals (collect, Arrays.asList (1, 2));

אנחנו צריכים לאסוף ימין זרם לרשימה, כדי למנוע java.lang.IllegalStateException: זרם כבר הופעל או נסגר. לאחר מכן, עלינו לבצע פעולת תופעת לוואי על ידי גישה ל- rightCollected רשימה מתוך א לְסַנֵן שיטה. זוהי דרך נוטה לשגיאה ולא דרך אלגנטית להצטרף לשני מערכי נתונים.

לְמַרְבֶּה הַמַזָל,רצף יש שיטות שימושיות לבצע הצטרפות פנימית, שמאלית וימינה בערכות נתונים. שיטות אלה מסתירות יישום של חשיפת API אלגנטית.

אנו יכולים לבצע הצטרפות פנימית באמצעות innerJoin () שיטה:

assertEquals (Seq.of (1, 2, 4) .innerJoin (Seq.of (1, 2, 3), (a, b) -> a == b). toList (), Arrays.asList (tuple (1 , 1), tuple (2, 2)));

אנחנו יכולים לעשות ימין ושמאל מצטרף בהתאם:

assertEquals (Seq.of (1, 2, 4). leftOuterJoin (Seq.of (1, 2, 3), (a, b) -> a == b). toList (), Arrays.asList (tuple (1 , 1), tuple (2, 2), tuple (4, null))); assertEquals (Seq.of (1, 2, 4) .rightOuterJoin (Seq.of (1, 2, 3), (a, b) -> a == b). toList (), Arrays.asList (tuple (1 , 1), tuple (2, 2), tuple (null, 3)));

יש אפילו א crossJoin () שיטה המאפשרת ליצור צירוף קרטזי של שני מערכי נתונים:

assertEquals (Seq.of (1, 2) .crossJoin (Seq.of ("A", "B")). toList (), Arrays.asList (tuple (1, "A"), tuple (1, "B "), tuple (2," A "), tuple (2," B ")));

5.3. מניפולציה א רצף

רצף יש שיטות שימושיות רבות לתמרון רצפים של אלמנטים. בואו נסתכל על כמה מהם.

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

assertEquals (Seq.of (1, 2, 3) .cycle (). limit (9) .toList (), Arrays.asList (1, 2, 3, 1, 2, 3, 1, 2, 3));

בואו נגיד שאנחנו רוצים לשכפל את כל האלמנטים מרצף אחד לרצף השני. ה לְשַׁכְפֵּל() השיטה עושה בדיוק את זה:

assertEquals (Seq.of (1, 2, 3). duplicate (). map ((first, second) -> tuple (first.toList (), second.toList ())), tuple (Arrays.asList (1, 2, 3), Arrays.asList (1, 2, 3))); 

סוג חוזר של a לְשַׁכְפֵּל() השיטה היא כפל של שני רצפים.

בואו נגיד שיש לנו רצף של מספרים שלמים ואנחנו רוצים לפצל את הרצף לשני רצפים בעזרת פרדיקט כלשהו. אנחנו יכולים להשתמש ב- חֲלוּקָה() שיטה:

assertEquals (Seq.of (1, 2, 3, 4). partition (i -> i> 2) .map ((first, second) -> tuple (first.toList (), second.toList ())), tuple (Arrays.asList (3, 4), Arrays.asList (1, 2)));

5.4. אלמנטים מקבצים

קיבוץ אלמנטים לפי מפתח באמצעות זרם API הוא מסורבל ולא אינטואיטיבי - כי אנחנו צריכים להשתמש בו לאסוף() שיטה עם Collectors.groupingBy אַסְפָן.

רצף מסתיר את הקוד מאחורי a groupBy () שיטה שחוזרת מַפָּה כך שאין צורך להשתמש ב- לאסוף() שיטה במפורש:

מַפָּה expectAfterGroupBy = HashMap חדש (); expectAfterGroupBy.put (1, Arrays.asList (1, 3)); expectAfterGroupBy.put (0, Arrays.asList (2, 4)); assertEquals (Seq.of (1, 2, 3, 4) .groupBy (i -> i% 2), expectAfterGroupBy);

5.5. אלמנטים מדלגים

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

אנחנו יכולים להשתמש ב- skipWhile () שיטה לכך:

assertEquals (Seq.of (1, 2, 3, 4, 5) .skipWhile (i -> i <3). toList (), Arrays.asList (3, 4, 5));

אנו יכולים להשיג את אותה התוצאה באמצעות skipUntil () שיטה:

assertEquals (Seq.of (1, 2, 3, 4, 5) .skipUntil (i -> i == 3). toList (), Arrays.asList (3, 4, 5));

5.6. רוכסן ריצפים

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

ה רוכסן() ממשק API שניתן להשתמש בו כדי לרכז שני רצפים לאחד:

assertEquals (Seq.of (1, 2, 3). zip (Seq.of ("a", "b", "c")). toList (), Arrays.asList (tuple (1, "a"), tuple (2, "b"), tuple (3, "c")));

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

כאשר אנו רוכסות שני רצפים, אך אנו רוצים לרכוס אותם באופן ספציפי שנוכל להעביר BiFunction אל א רוכסן() שיטה המגדירה את הדרך של רוכסן אלמנטים:

assertEquals (Seq.of (1, 2, 3). zip (Seq.of ("a", "b", "c"), (x, y) -> x + ":" + y). toList ( ), Arrays.asList ("1: a", "2: b", "3: c"));

לפעמים, כדאי לרכוס רצף עם אינדקס של אלמנטים ברצף זה, דרך ה- zipWithIndex () ממשק API:

assertEquals (Seq.of ("a", "b", "c"). zipWithIndex (). toList (), Arrays.asList (tuple ("a", 0L), tuple ("b", 1L), tuple ("c", 2L)));

6. המרת חריגים מסומנים ללא סימון

נניח שיש לנו שיטה שלוקחת מחרוזת ויכולה לזרוק חריג מסומן:

שיטת מספר שלם ציבוריThatThrowsChecked (מחרוזת arg) זורק Exception {return arg.length (); }

ואז אנו רוצים למפות אלמנטים של א זרם החלת שיטה זו על כל אלמנט. אין שום דרך להתמודד עם חריג זה גבוה יותר ולכן עלינו לטפל בחריג זה ב מַפָּה() שיטה:

רשימה collect = Stream.of ("a", "b", "c"). מפה (elem -> {try {return methodThatThrowsChecked (elem);} לתפוס (Exception e) {e.printStackTrace (); לזרוק RuntimeException חדש (ה);}}). אסוף (Collectors.toList ()); assertEquals (collect, Arrays.asList (1, 1, 1));

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

למרבה המזל, ב- jOOL יש לא בדוק מחלקה הכוללת שיטות שיכולות להמיר חריגים מסומנים לחריגים לא מסומנים:

List collect = Stream.of ("a", "b", "c") .map (Unchecked.function (elem -> methodThatTrowsChecked (elem))) .collect (Collectors.toList ()); assertEquals (collect, Arrays.asList (1, 1, 1));

אנו עוטפים שיחה אל methodThatThrowsChecked () לתוך Unchecked.function () שיטה המטפלת בהמרת חריגים שמתחת.

7. מסקנה

מאמר זה מראה כיצד להשתמש בספריית jOOL המוסיפה שיטות נוספות שימושיות לתקן Java זרם ממשק API.

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


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