כיצד להתחיל לעבוד עם Lambda Expressions בג'אווה

לפני שנוספה תמיכת ביטויים למבדה על ידי JDK 8, השתמשתי רק בדוגמאות שלהם בשפות כמו C # ו- C ++.

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

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

מבוא מהיר

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

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

ממשק פונקציונלי

ממשק פונקציונלי הוא ממשק המכיל שיטה מופשטת אחת ויחידה.

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

במדגם הקוד שלמטה, השיטה computeNameהיא מופשטת באופן משתמע והיא השיטה היחידה שהוגדרה, מה שהופך את MyName לממשק פונקציונלי.

interface MyName{ String computeName(String str); }

מפעיל החץ

ביטויי למבה מכניסים את מפעיל החץ החדש ->לג'אווה. הוא מחלק את ביטויי הלמבה לשני חלקים:

(n) -> n*n

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

הצד הימני הוא גוף הלמבה המפרט את פעולות הביטוי למבדה. יכול להיות מועיל לחשוב על מפעיל זה כ"הופך ". לדוגמה, "n הופך ל- n * n", או "n הופך ל- n בריבוע".

מתוך מחשבה על ממשק פונקציונלי ומושגי מפעיל חץ, תוכל להרכיב ביטוי למבדה פשוט:

interface NumericTest { boolean computeTest(int n); } public static void main(String args[]) { NumericTest isEven = (n) -> (n % 2) == 0; NumericTest isNegative = (n) -> (n < 0); // Output: false System.out.println(isEven.computeTest(5)); // Output: true System.out.println(isNegative.computeTest(-5)); }
interface MyGreeting { String processName(String str); } public static void main(String args[]) { MyGreeting morningGreeting = (str) -> "Good Morning " + str + "!"; MyGreeting eveningGreeting = (str) -> "Good Evening " + str + "!"; // Output: Good Morning Luis! System.out.println(morningGreeting.processName("Luis")); // Output: Good Evening Jessica! System.out.println(eveningGreeting.processName("Jessica")); }

המשתנים morningGreetingו eveningGreeting, קווי 6 ו 7 במדגם הנ"ל, לבצע הפנית MyGreetingהממשק ולהגדיר ביטויי ברכה שונים.

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

MyGreeting morningGreeting = (String str) -> "Good Morning " + str + "!"; MyGreeting eveningGreeting = (String str) -> "Good Evening " + str + "!";

חסום ביטויים למבדה

עד כה כיסיתי דוגמאות של למבדות ביטוי יחיד. ישנו סוג אחר של ביטוי המשמש כאשר הקוד בצד ימין של אופרטור החץ מכיל יותר מהצהרה אחת המכונה block lambdas :

interface MyString { String myStringFunction(String str); } public static void main (String args[]) { // Block lambda to reverse string MyString reverseStr = (str) -> { String result = ""; for(int i = str.length()-1; i >= 0; i--) result += str.charAt(i); return result; }; // Output: omeD adbmaL System.out.println(reverseStr.myStringFunction("Lambda Demo")); }

ממשקים פונקציונליים כלליים

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

interface MyGeneric { T compute(T t); } public static void main(String args[]){ // String version of MyGenericInteface MyGeneric reverse = (str) -> { String result = ""; for(int i = str.length()-1; i >= 0; i--) result += str.charAt(i); return result; }; // Integer version of MyGeneric MyGeneric factorial = (Integer n) -> { int result = 1; for(int i=1; i <= n; i++) result = i * result; return result; }; // Output: omeD adbmaL System.out.println(reverse.compute("Lambda Demo")); // Output: 120 System.out.println(factorial.compute(5)); }

ביטויים למבדה כטיעונים

שימוש נפוץ אחד במבשרות הוא להעבירם כוויכוחים.

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

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

interface MyString { String myStringFunction(String str); } public static String reverseStr(MyString reverse, String str){ return reverse.myStringFunction(str); } public static void main (String args[]) { // Block lambda to reverse string MyString reverse = (str) -> { String result = ""; for(int i = str.length()-1; i >= 0; i--) result += str.charAt(i); return result; }; // Output: omeD adbmaL System.out.println(reverseStr(reverse, "Lambda Demo")); }

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