מבוא לג'אווה פונקציונלית

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

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

2. ספריית Java הפונקציונלית

ספריית Java הפונקציונלית היא ספריית קוד פתוח שנועדה להקל על תכנות פונקציונלי ב- Java. הספרייה מספקת הרבה תקצירי תכנות בסיסיים ומתקדמים הנפוצים בתכנות פונקציונליות.

חלק ניכר מהפונקציונליות של הספרייה סובבת סביב F מִמְשָׁק. זֶה F ממשק מדגמן פונקציה שלוקחת קלט מסוג א ומחזירה פלט מסוג ב. כל זה בנוי על גבי מערכת הסוג של Java עצמה.

3. תלות Maven

ראשית, עלינו להוסיף את התלות הנדרשת שלנו pom.xml קוֹבֶץ:

 org.functionaljava functionjava 4.8.1 org.functionaljava functionjava-java8 4.8.1 org.functionaljava functionjava-quickcheck 4.8.1 org.functionaljava functionjava-java-core 4.8.1 

4. הגדרת פונקציה

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

ללא Java פונקציונלי, שיטת כפל בסיסית תיראה בערך כמו:

סופי ציבורי סטטי ציבורי זמנים שלמים שני רגולרי (שלם i) {החזר i * 2; }

באמצעות ספריית Java הפונקציונלית, אנו יכולים להגדיר פונקציונליות זו מעט יותר באלגנטיות:

סופי ציבורי סטטי ציבורי F timesTwo = i -> i * 2;

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

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

סופי סטטי ציבורי F isEven = i -> i% 2 == 0;

5. יישום פונקציה

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

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

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

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

חלל ציבורי multiplyNumbers_givenIntList_returnTrue () {List fList = List.list (1, 2, 3, 4); רשימה fList1 = fList.map (timesTwo); רשימה fList2 = fList.map (i -> i * 2); assertTrue (fList1.equals (fList2)); }

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

הנה דוגמה דומה לשימוש שלנו isEven פוּנקצִיָה:

חלל ציבורי calcEvenNumbers_givenIntList_returnTrue () {List fList = List.list (3, 4, 5, 6); רשימת evenList = fList.map (isEven); רשימת evenListTrueResult = List.list (שקר, נכון, שקר, נכון); assertTrue (evenList.equals (evenListTrueResult)); }

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

חלל ציבורי applyMultipleFunctions_givenIntList_returnFalse () {List fList = List.list (1, 2, 3, 4); רשימה fList1 = fList.map (timesTwo) .map (plusOne); רשימה fList2 = fList.map (plusOne) .map (timesTwo); assertFalse (fList1.equals (fList2)); }

תפוקת הרשימות שלעיל תהיה:

רשימה (3,5,7,9) רשימה (4,6,8,10)

6. סינון באמצעות פונקציה

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

עכשיו, בואו נשתמש שלנו הוא אפילו פונקציה לסינון המספרים האי זוגיים ממערך קלט באמצעות ה- לְסַנֵן שיטה:

filter void filterList_givenIntList_returnResult () {Array array = Array.array (3, 4, 5, 6); מערך filteredArray = array.filter (isEven); תוצאת מערך = Array.array (4, 6); assertTrue (filteredArray.equals (תוצאה)); }

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

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

7. יישום לוגיקה בוליאנית באמצעות פונקציה

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

ספריית Java הפונקציונלית מספקת לנו קיצורי דרך להיגיון זה דרך ה- קיים וה לכולם שיטות:

check void checkForLowerCase_givenStringArray_returnResult () {Array array = Array.array ("ברוך הבא", "To", "baeldung"); assertTrue (array.exists (s -> List.fromString (s) .forall (Characters.isLowerCase))); מערך מערך 2 = Array.array ("ברוך הבא", "To", "Baeldung"); assertFalse (array2.exists (s -> List.fromString (s) .forall (Characters.isLowerCase))); assertFalse (array.forall (s -> List.fromString (s) .forall (Characters.isLowerCase))); }

בדוגמה שלמעלה השתמשנו במערך מחרוזות כקלט שלנו. קורא ל fromString הפונקציה תמיר כל אחד מהמחרוזות מהמערך לרשימת תווים. לכל אחת מאותן רשימות הגשנו בקשה forall (Characters.isLowerCase).

כפי שבטח ניחשתם, תווים.isLowerCase היא פונקציה שמחזירה אמת אם תו באותיות קטנות. אז פונים forall (Characters.isLowerCase) לרשימת תווים רק יחזור נָכוֹן אם הרשימה כולה מורכבת מדמויות קטנות, אשר מצידן מציין שהמחרוזת המקורית הייתה כולה באותיות קטנות.

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

8. טיפול בערכים אופציונליים עם פונקציה

בדרך כלל דרוש טיפול בערכים אופציונליים בקוד == null אוֹ isNotBlank צ'קים. Java 8 מספק כעת את אופציונאלי בכיתה כדי לטפל בבדיקות אלו בצורה אלגנטית יותר, וספריית Java הפונקציונלית מציעה מבנה דומה להתמודדות עם נתונים חסרים בחינניות באמצעות מחלקת האופציות שלה:

בטל פומבי checkOptions_givenOptions_returnResult () {Option n1 = Option.some (1); אפשרות n2 = Option.some (2); אפשרות n3 = Option.none (); F function = i -> i% 2 == 0? Option.some (i + 100): Option.none (); אפשרות result1 = n1.bind (פונקציה); אפשרות result2 = n2.bind (פונקציה); אפשרות result3 = n3.bind (פונקציה); assertEquals (Option.none (), result1); assertEquals (Option.some (102), result2); assertEquals (Option.none (), result3); }

9. צמצום סט באמצעות פונקציה

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

ספריית Java הפונקציונלית מתייחסת לפונקציונליות זו כקיפול.

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

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

ריק ריק ציבורי foldLeft_givenArray_returnResult () {Array intArray = Array.array (17, 44, 67, 2, 22, 80, 1, 27); int sumAll = intArray.foldLeft (Integers.add, 0); assertEquals (260, sumAll); int sumEven = intArray.filter (isEven) .foldLeft (Integers.add, 0); assertEquals (148, sumEven); }

הראשון foldLeft פשוט מוסיף את כל המספרים השלמים. ואילו השני יחיל תחילה מסנן ואז יוסיף את המספרים השלמים הנותרים.

10. מסקנה

מאמר זה הוא רק הקדמה קצרה לספריית Java הפונקציונלית.

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


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