English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
في هذا المقال، سنفهم عبر الأمثلة تعبيرات lambda في Java، وكيفية استخدامها مع واجهات الوظائف، والوظائف العامة، وواجهات API للتحويل.
تم إدخال تعبيرات lambda لأول مرة في Java 8. هدفيها الرئيسي هو زيادة قدرة اللغة على التعبير.
لكن، قبل التعرف على lambda، نحتاج أولاً إلى فهم واجهة وظيفية.
إذا كانت واجهة Java تحتوي فقط على طريقة抽象ة واحدة، فيُسمى واجهة وظيفية. يحدد هذا الطريقة واحدة استخدام الواجهة المتوقع.
على سبيل المثال، واجهة Runnable في حزمة java.lang هي واجهة وظيفية، لأنها تتكون من طريقة واحدة فقط، وهي run().
import java.lang.FunctionalInterface; @FunctionalInterface public interface MyInterface{ //طريقة抽象ة واحدة double getValue(); }
في المثال السابق، يحتوي واجهة MyInterface على طريقة抽象ة واحدة getValue(). لذلك، هي واجهة وظيفية.
في هذا المكان، استخدمنا التعليق @FunctionalInterface. هذا التعليق يتطلب من مشغل Java إشارة إلى أن هذا الجهاز هو جهاز وظيفي. لذلك، لا يسمح بوجود أكثر من طريقة抽象ة. ولكن، ليس إلزامياً.
In Java 7, functional interfaces are consideredSingle Abstract Method (SAM)Type. In Java 7, SAM types are usually implemented through anonymous classes.
public class FunctionInterfaceTest { public static void main(String[] args) { // Anonymous class new Thread(new Runnable() { @Override public void run() { System.out.println("I just implemented the Runnable functional interface."); } }).start(); } }
الناتج:
I just implemented the Runnable functional interface.
Here, we can pass an anonymous class to a method. This helps write less code with Java 7. However, the syntax is still difficult and requires a large number of additional code lines.
Java 8 further extends the functionality of SAM. Since we know that a functional interface has only one method, there is no need to define the name of the method when passing it as a parameter. Lambda expressions allow us to do this.
Lambda expressions are essentially anonymous or unnamed methods. Lambda expressions cannot be executed independently. Instead, they are used to implement methods defined by functional interfaces.
This is how we define lambda expressions in Java.
(parameter list) -> lambda body
The new operator (->) used is called the arrow operator or lambda operator. Let's explore some examples,
Suppose we have a method like this:
double getPiValue() { return 3.1415; }
We can write this method using a lambda expression as follows:
() -> 3.1415
Here, the method has no parameters. Therefore, the left side of the operator includes an empty parameter. The right side is the lambda body, which specifies the operation of the lambda expression. In this case, it will return the value 3.1415.
In Java, there are two types of lambda bodies.
1. Single expression body
() -> System.out.println("Lambdas are great");
zhe zhong lei xing de lambda ti shen wei biao da shi ti.}
2. you dian hua ku zu cheng de ti shen.
() -> { double pi = 3.1415; return pi; };
zhe zhong lei xing de lambda ti wei ku ti. Ku ti zhi ni huan liang biao da shi ti huan neng chan ren duo ge yu ju. Zhe xie yu ju chan rong zai gua hao nei, ni zai gua hao hou jia rong hao.
zhu yi:dai li ku ti, ni ying gai zhi yuan you yi ge return yu ju. Dan shi, dan yi ge biao da shi ti shen bu xui yao return yu ju.
rang women xie yi ge Java cheng xu, zhe ge cheng xu shi yong lambda biao da shi huan hui Pi de zhi.
ru qian shuo de yi yang, lambda biao da shi bu shi dan dan ji xing de. Fang ci, ta xing cheng le you gong neng jie kou ding yi de chou xiang fa de shi li.
yu ci, women xui xiang shi xian yi ge gong neng jie kou.
import java.lang.FunctionalInterface; //zhe shi you xiao de jie kou @FunctionalInterface interface MyInterface{ // chou xiang fa double getPiValue(); } public class الرئيسي { public static void main(String[] args) { //dian sheng dui MyInterface de yin zhuan MyInterface ref; // lambda biao da shi ref = () -> 3.1415; System.out.println("Pi = " + ref.getPiValue()); } }
الناتج:
Pi = 3.1415
zai yi shang shi li,
women chuang jian le yi ge ming ming wei MyInterface de gong neng jie kou. Ta bao han yi ge ming ming wei getPiValue() de chou xiang fa huo
zai Main lei nei, women sheng dian le dui MyInterface de yin zhuan. Qing zhong yao, women neng sheng dian jie kou de yin zhuan, dan bu neng shi li hua jie kou. Na shi yin wei,
//ta jiang bao tuo yi ge cuo wu MyInterface ref = new myInterface(); // zhe shi you xiao de MyInterface ref;
ren hou, women wei zhuan yin fen zuo le yi ge lambda biao da shi.
ref = () -> 3.1415;
zui hou, women shi yong zhuan jie jie kou diao yong fa huo getPiValue().
System.out.println("Pi = " + ref.getPiValue());
dao zhe ming qian, women ying cheng le bu dai ren he can shu de lambda biao da shi. Dan shi, ni hao yu fa huo, lambda biao da shi ye kai you can shu. Li ran,
(n) -> (n%2)==0
zai ci, gua hao nei de bian liang n shi chuan da gei lambda biao da shi de can shu. Lambda ti shi jie shou can shu bing jian cha ta shi ou shu huan shi ji shu.
@FunctionalInterface interface MyInterface { //chou xiang fa String reverse(String n); } public class الرئيسي { public static void main(String[] args) { //dian sheng dui MyInterface de yin zhuan // تخصيص تعبير لامبدا للاشارة MyInterface ref = (str) -> { String الناتج = ""; لِلدوران (للعدد i = str.length() - 1; i >= 0; i--) الناتج += str.charAt(i); } يعودُ الناتج; }; // استدعاء طريقة الواجهة System.out.println("Lambda reversed = " + ref.reverse("Lambda")); } }
الناتج:
Lambda reversed = adbmaL
حتى الآن، لقد استخدمنا واجهات وظيفية تقبل فقط قيمة نوع واحدة. مثل،
@FunctionalInterface interface MyInterface { String reverseString(String n); }
واجهة الوظيفة هذه تقبل فقط String وتعيد String. ولكن يمكننا جعل واجهة الوظيفة عامة حتى تقبل أي نوع بيانات. إذا لم تكن مطلعاً على الجينراتيكا، يرجى زيارةالجينراتيكا في بايثون.
// GenericInterface.java @FunctionalInterface interface GenericInterface<T> { // طريقة عامة T func(T t); } // GenericLambda.java public class الرئيسي { public static void main(String[] args) { // إعلان مرجع لـ GenericInterface // GenericInterface يعمل على البيانات النصية // تخصيص تعبير لامبدا GenericInterface<String> العكس = (str) -> { String الناتج = ""; لِلدوران (للعدد i = str.length() - 1; i >= 0; i--) الناتج += str.charAt(i); يعودُ الناتج; }; System.out.println("Lambda reversed = " + reverse.func("Lambda")); // إعلان مرجع آخر لـ GenericInterface // GenericInterface يعمل على البيانات الصحيحة // تخصيص تعبير لامبدا GenericInterface<Integer> الفاكسوريال = (n) -> { العدد int الناتج = 1; لِلدوران (للعدد i = 1; i <= n; i++) الناتج = i * الناتج; يعودُ الناتج; }; System.out.println("5! = " + factorial.func(5)); } }
الناتج:
Lambda reversed = adbmaL 5! = 120
في المثال السابق، قمنا بإنشاء فئة GenericInterface بتصميم عام. يحتوي على طريقة عامة تسمى func().
داخل الفئة:
GenericInterface<String> reverse - إنشاء مرجع إلى هذا الوجهة. الآن، يمكن للوجهة معالجة بيانات نوع String.
GenericInterface<Integer> factorial - إنشاء مرجع إلى هذا الوجهة. في هذه الحالة، يقوم الوجهة بمعالجة بيانات نوع Integer.
الجديدjava.util.streamتم إضافة الحزمة إلى JDK8، مما يسمح للمطورين Java بتنفيذ عمليات البحث والفرز والتحويل والتصغير وما إلى ذلك، أو عمليات القوائم وما إلى ذلك من المجموعات.
على سبيل المثال، لدينا جريان بيانات (في مثالنا هو قائمة من الأنواع)، حيث كل نوع هو اسم دولة ومقاطعة/منطقة. الآن، يمكننا معالجة هذا الجريان بيانات، وتميز المواقع من نيبال فقط.
لهذا، يمكننا الجمع بين استخدام API للجريان وعبارة Lambda لتنفيذ عمليات جماعية في الجريان.
import java.util.ArrayList; import java.util.List; public class StreamMain { //使用ArrayList创建一个列表对象 static List<String> places = new ArrayList<>(); //准备我们的数据 public static List getPlaces(){ //将地点和国家添加到列表中 places.add("Nepal, Kathmandu"); places.add("Nepal, Pokhara"); places.add("India, Delhi"); places.add("USA, New York"); places.add("Africa, Nigeria"); return places; } public static void main(String[] args) { List<String> myPlaces = getPlaces(); System.out.println("الأماكن من نيبال:"); myPlaces.stream() .filter((p) -> p.startsWith("Nepal")) .map((p) -> p.toUpperCase()) .sorted() .forEach((p) -> System.out.println(p)); } }
الناتج:
الأماكن من نيبال: NEPAL, KATHMANDU NEPAL, POKHARA
في المثال أعلاه، لاحظ الآتي:
myPlaces.stream() .filter((p) -> p.startsWith("Nepal")) .map((p) -> p.toUpperCase()) .sorted() .forEach((p) -> System.out.println(p));
في هذا السياق، نستخدم Stream API methods مثل filter()، map() و forEach() وما إلى ذلك. يمكن لهذه الطرق استقبال تعبيرات lambda كمدخل.
يمكننا تعريف تعبيراتنا الخاصة بناءً على الجملة التي تعلمناها. كما هو موضح في المثال أعلاه، هذا يمكن أن يقلل من عدد سطور الكود بشكل كبير.