logo

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

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

מ-Java 8 ואילך ניתן להשתמש בביטויי lambda והפניות לשיטה כדי לייצג את המופע של ממשק פונקציונלי.



דוגמה: שימוש בממשק פונקציונלי עם ביטוי למבדה

Java
public class Geeks {    public static void main(String[] args) {    // Using lambda expression to implement Runnable  new Thread(() -> System.out.println('New thread created')).start();  } } 

תְפוּקָה
New thread created 

הֶסבֵּר:

  • התוכנית שלמעלה מדגימה שימוש בביטוי למבדה עם הממשק הפונקציונלי Runnable.
  • ל-Runnable יש שיטה אבסטרקטית אחת run() כך שהוא מתאים כממשק פונקציונלי.
  • Lambda ()-> System.out.println('שרשור חדש נוצר') מגדיר את שיטת run() .
  • new Thread().start() מתחיל שרשור חדש שמבצע את גוף lambda

פֶּתֶק:

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



@FunctionalInterface ביאור

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

פֶּתֶק:

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



דוגמה: הגדרת ממשק פונקציונלי עם הערת @FunctionalInterface

Java
@FunctionalInterface interface Square {  int calculate(int x); } class Geeks {  public static void main(String args[]) {  int a = 5;  // lambda expression to define the calculate method  Square s = (int x) -> x * x;  // parameter passed and return type must be same as defined in the prototype  int ans = s.calculate(a);  System.out.println(ans);  } } 

תְפוּקָה
25 

הֶסבֵּר :

גלילה בעכבר לא עובדת
  • ריבוע הוא ממשק פונקציונלי עם שיטה יחידה calculate(int x).
  • ביטוי למבדה (int x) -> x * x משמש ליישום שיטת החישוב.
  • למדה לוקחת את x כקלט ומחזירה את x * x.

ממשקים פונקציונליים של Java לפני Java 8

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

דוּגמָה: תוכנית Java להדגמת ממשק פונקציונלי

Java
class Geeks {  public static void main(String args[]) {    // create anonymous inner class object  new Thread(new Runnable() {  @Override public void run()  {  System.out.println('New thread created');  }  }).start();  } } 

תְפוּקָה
New thread created 

ממשקי Java פונקציונליים מובנים

מאז Java SE 1.8 ואילך ישנם ממשקים רבים המומרים לממשקים פונקציונליים. כל הממשקים הללו מסומנים עם @FunctionalInterface. ממשקים אלה הם כדלקמן:

  • ניתן להרצה: ממשק זה מכיל רק את לָרוּץ() שִׁיטָה.
  • בר השוואה: ממשק זה מכיל רק את שיטת compareTo()‎.
  • ActionListener: ממשק זה מכיל רק את שיטת actionPerformed() .
  • ניתן להתקשרות: ממשק זה מכיל רק את השיטה call().

סוגי ממשקים פונקציונליים ב-Java

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

  1. צַרכָן
  2. לְבַסֵס
  3. פוּנקצִיָה 
  4. סַפָּק

1. צרכן 

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

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

תַחבִּיר:

צַרכָן consumer = (value) -> System.out.println(value);

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

2. פרדיקט 

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

תַחבִּיר: 

פרדיקט ממשק ציבורי{
   מבחן בוליאני (T t);
}

ניתן ליישם את הממשק הפונקציונלי של ג'אווה באמצעות ביטויי Lambda.

גדלי גופן בלטקס

לְבַסֵס פרדיקט = (ערך) -> ערך != null;

3. פונקציה

א פוּנקצִיָה הוא סוג של ממשק פונקציונלי ב-Java שמקבל רק ארגומנט בודד ומחזיר ערך לאחר העיבוד הנדרש. גרסאות רבות ושונות של ממשקי הפונקציות הן אינסטרומנטליות ונפוצות בשימוש בטיפוסים פרימיטיביים כמו double int long.

תַחבִּיר:

פוּנקצִיָה function = (ערך) -> ערך * ערך;

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

4. ספק

ה סַפָּק ממשק פונקציונלי הוא גם סוג של ממשק פונקציונלי שאינו לוקח שום קלט או ארגומנט ובכל זאת מחזיר פלט בודד. ההרחבות השונות של הממשק הפונקציונלי של ספק מכילות פונקציות רבות אחרות של ספקים כמו Boolean Supplier DoubleSupplier LongSupplier ו IntSupplier . סוג ההחזר של כל ההתמחויות הנוספות הללו הוא הפרימיטיבים המקבילים שלהם בלבד. 

תַחבִּיר:

סַפָּקספק = () -> 'שלום עולם!';

דוּגמָה: שימוש בממשק Predicate לסינון מחרוזות

Java
import java.util.*; import java.util.function.Predicate; class Geeks {  public static void main(String args[]) {    // create a list of strings  List<String> n = Arrays.asList('Geek' 'GeeksQuiz' 'g1' 'QA' 'Geek2');  // declare the predicate type as string and use lambda expression to create object  Predicate<String> p = (s) -> s.startsWith('G');  // Iterate through the list  for (String st : n) {    // call the test method  if (p.test(st))  System.out.println(st);  }  } } 

תְפוּקָה
Geek GeeksQuiz Geek2 

טבלת ממשקים פונקציונליים

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

תֵאוּר

שִׁיטָה

ניתן להרצה

זה מייצג משימה שניתן לבצע באמצעות שרשור.

void run()

בר השוואה

זה משווה שני אובייקטים להזמנה.

int compareTo(T o)

ActionListener

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

void actionPerformed(ActionEvent ה)

ניתן להתקשרות

זה מייצג משימה שיכולה להחזיר תוצאה או לזרוק חריגה.

V call() זורק Exception

צַרכָן

הוא מקבל ארגומנט קלט בודד ולא מחזיר תוצאה.

void accept(T t)

לְבַסֵס

ציור מלבן gimp

הוא מקבל ארגומנט בודד ומחזיר תוצאה בוליאנית.

מבחן בוליאני (T t)

פוּנקצִיָה

הוא מקבל טיעון יחיד ומחזיר תוצאה.

R להחיל (T t)

סַפָּק

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

T get()

BiConsumer

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

void accept(T t U u)

BiPredicate

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

מבחן בוליאני (T t U u)

BiFunction

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

R להחיל (T t U u)

UnaryOperator

להפוך מחרוזת ל-int

זהו מקרה מיוחד של Function שבו סוגי הקלט והפלט זהים.

T החל (T t)

BinaryOperator

זהו מקרה מיוחד של BiFunction שבו סוגי הקלט והפלט זהים.

T חל (T t1 T t2)

מאמרים קשורים

  • Java 8
  • Java Lambda Expressions