يسمى Java 8 النسخة الأكثر تغيرًا في تاريخ Java. أنه يحتوي على العديد من الميزات الجديدة المهمة ، والأكثر جوهرًا هو إضافة تعبيرات Lambda و Streamapi. يمكن أيضًا استخدام الاثنين معًا. أولاً ، دعنا نلقي نظرة على ما هو تعبير Lambda.
إن استخدام تعبيرات Lambda لا يجعل الرمز بسيطًا فحسب ، بل يمكن قراءته أيضًا ، والأهم من ذلك ، أن كمية الكود تنخفض أيضًا كثيرًا. ومع ذلك ، إلى حد ما ، تم استخدام هذه الوظائف على نطاق واسع في لغات JVM مثل Scala.
ليس من المستغرب أن يكون مجتمع سكالا لا يصدق ، لأن الكثير من محتوى Java 8 يبدو أنه تم نقله من Scala. إلى حد ما ، فإن بناء جملة Java 8 أكثر تفصيلاً ولكنه ليس واضحًا جدًا من Scala ، لكن هذا لا يقول الكثير ، وإذا كان بإمكانه ذلك ، فقد يبني تعبيرات Lambda مثل Scala.
من ناحية ، إذا استمرت Java في تطوير وتنفيذ الوظائف التي نفذها Scala بالفعل حول Lambda ، فقد لا تكون هناك حاجة إلى Scala. من ناحية أخرى ، إذا كانت توفر فقط بعض الميزات الأساسية ، مثل مساعدة الفصول الداخلية المجهولة ، ستستمر Scala واللغات الأخرى في الازدهار وقد تتفوق على Java. في الواقع ، هذه هي أفضل نتيجة. فقط مع المنافسة يمكن أن يكون هناك تقدم. تستمر اللغات الأخرى في التطور والنمو ، وليس هناك حاجة للقلق بشأن ما إذا كانت ستصبح قديمة.
تعبير Lambda ، التفسير على Wikipedia هو مشغل يستخدم لتمثيل وظائف وإغلاق مجهول. أشعر أن هذا التفسير لا يزال مجردة للغاية. دعونا نلقي نظرة على مثال.
الفئة العامة swingtest {public static void main (string [] args) {jframe jframe = new JFrame ("my jframe") ؛ jbutton jbutton = new jbutton ("my jbutton") ؛ jButton.AddActionListener (new ActionListener () {Override public void actionperformed (ActionEvent e) {system.out.println ("button pressed!") ؛}}) ؛ jframe.add (jbutton) ؛ jframe.pack () ؛ jframe.setVisible (صحيح) ؛ jframe.setDefaultCloseOperation (jframe.exit_on_close) ؛ }}هذا جزء من التعليمات البرمجية في البرمجة الأرجوحة التي تربط حدث الاستماع إلى الزر. عند النقر فوق الزر ، فإن المحتوى "buttonpressed!" سيتم الإخراج على وحدة التحكم. هنا نقوم بإنشاء مثيل لفئة داخلية مجهولة المصدر لربط المستمع ، وهو أيضًا نموذج منظمة رمز شائع نسبيًا في الماضي. ولكن إذا نظرنا عن كثب ، فسنجد أنه في الواقع ، ما نركز عليه حقًا هو معلمة من نوع ActionEvent ونظام البيانات. الإخراج إلى وحدة التحكم.
إذا تم استبدال الكود في البرنامج السابق الذي ينشئ فئة داخلية مجهولة المصدر بتعبير lambda ، فإن الكود كما يلي
الفئة العامة swingtest {public static void main (string [] args) {jframe jframe = new JFrame ("my jframe") ؛ jbutton jbutton = new jbutton ("my jbutton") ؛ jButton.AddActionListener (e -> system.out.println ("button pressed!")) ؛ jframe.add (jbutton) ؛ jframe.pack () ؛ jframe.setVisible (صحيح) ؛ jframe.setDefaultCloseOperation (jframe.exit_on_close) ؛}} انتبه إلى التغييرات في الجزء الأوسط من الرمز ، من الأسطر الستة الأصلية من التعليمات البرمجية ، يمكن الآن تنفيذ سطر واحد. هذا هو شكل بسيط من التعبير lambda.
يمكن أن نرى أن بناء جملة تعبير Lambda هو
(param1 ، param2 ، param3) -> {// todo}يمكن استنتاج برنامج النوع للمعلمة هنا بناءً على السياق ، ولكن لا يمكن استنتاج جميع الأنواع. في هذا الوقت ، نحتاج إلى عرض نوع المعلمة المعلن. عندما يكون هناك معلمة واحدة فقط ، يمكن حذف الأقواس. عندما يحتوي جزء TODO على سطر واحد فقط من التعليمات البرمجية ، يمكن حذف الأقواس الموجودة في الخارج. كما في مثالنا أعلاه
لذا ، بالإضافة إلى الكود الموجز ، هل يجلب لنا تعبير Lambda أي تغييرات؟
دعونا نتذكر أنه في Java ، لا يمكننا تمرير وظيفة كمعلمة إلى طريقة ما ، ولا يمكننا أن نعلن أن قيمة الإرجاع هي وسيلة للدالة. قبل Java 8 ، كان الجواب نعم.
لذلك ، في المثال أعلاه ، يمكننا بالفعل تمرير جزء من منطق الرمز كمعلمة للمستمع ، وإخبار المستمع أنه يمكنك القيام بذلك عند تشغيل الحدث ، دون الحاجة إلى استخدام فئات داخلية مجهولة كمعلمات. هذه أيضًا ميزة جديدة أخرى قدمها Java 8: Programming.
هناك العديد من اللغات التي تدعم البرمجة الوظيفية. في JavaScript ، من الشائع جدًا تمرير الوظائف كمعلمات أو قيم إرجاع كوظائف. JavaScript هي لغة وظيفية شائعة جدًا.
يضيف Lambda ميزات البرمجة الوظيفية المفقودة إلى Java ، مما يسمح لنا بمعالجة الوظائف كمواطنين من الدرجة الأولى.
في لغات البرمجة الوظيفية ، يكون نوع تعبير Lambda وظيفة. في Java ، تعبيرات Lambda هي كائنات ، ويجب إرفاقها بواجهة وظيفية لكائن خاص.
بعد ذلك ، دعونا نلقي نظرة على تعريف الواجهة الوظيفية:
إذا كانت هناك طريقة مجردة واحدة فقط في واجهة (لا يتم تضمين الطرق في فئة الكائن) ، فيمكن اعتبار هذه الواجهة واجهة وظيفية.
واجهة functionalInterFacepublic Runnable {/** * عندما يتم استخدام كائن تنفيذ واجهة <code> RunNable </code> * لإنشاء مؤشر ترابط ، فإن بدء تشغيل مؤشر الترابط يتسبب في * الكائن <code> تشغيل </code> ليتم استدعاء طريقة تنفيذها بشكل منفصل * مؤشر ترابط. * <p> * العقد العام للطريقة <code> تشغيل </code> هو أنه قد يتخذ أي إجراء على الإطلاق. * * see java.lang.thread#run () */ public Abstract void run () ؛}دعنا نلقي نظرة على بيان الواجهة القابلة للتشغيل. بعد Java 8 ، تحتوي واجهة Runnable على شرح إضافي للواجهة الوظيفية ، مما يشير إلى أن الواجهة هي واجهة وظيفية. ومع ذلك ، إذا لم نضيف توضيح الواجب الوظيفي ، إذا كانت هناك طريقة مجردة واحدة فقط في الواجهة ، فسوف يعتبر المترجم أيضًا الواجهة كواجهة وظيفية.
functionalInterFacepublic interface myInterface {void test () ؛ سلسلة tostring () ؛}MyInterface هي أيضًا واجهة وظيفية ، لأن ToString () هي طريقة في فئة الكائن ، ولكن يتم إعادة كتابتها هنا ولن تزيد من عدد الأساليب المجردة في الواجهة.
(لذكر هنا ، في Java 8 ، لا يمكن أن تحتوي الطرق الموجودة في الواجهة على طرق تجريدية فحسب ، بل تحتوي أيضًا على طرق محددة تنفذ. وتسمى الأساليب الافتراضية ، والتي سيتم تقديمها بالتفصيل لاحقًا)
منذ في جافا ، تعبيرات لامدا هي كائنات. إذن ما هو نوع هذا الكائن؟ دعنا نراجع برنامج SwingTest ، حيث يتم إنشاء مثيل واجهة ActionListener في فصل داخلي مجهول.
jButton.AddActionListener (new ActionListener () {Override public void actionperformed (ActionEvent e) {system.out.println ("button pressed!") ؛}}) ؛تحسن مع تعبير لامدا
jButton.AddActionListener (e -> system.out.println ("button pressed!")) ؛أي أننا نستخدم تعبير Lambda لإنشاء مثيل لواجهة ActionListener ، ثم ننظر إلى تعريف واجهة ActionListener.
يمتد ActionListener للواجهة العامة EventListener { /*** يتم استدعاؤه عند حدوث إجراء. */ public void actionperformed (Actionevent e) ؛} هناك طريقة مجردة واحدة فقط. على الرغم من عدم إضافة شرح الواجب الوظيفي ، إلا أنه يتوافق أيضًا مع تعريف الواجهة الوظيفية. سوف يعتبر المترجم أن هذا واجهة وظيفية.
لذلك ، يمكن أن يؤدي استخدام تعبيرات Lambda إلى إنشاء مثيلات الواجهات الوظيفية. وهذا هو ، تعبير Lambda يرجع نوع الواجهة الوظيفية.
في الواقع ، هناك ثلاث طرق لإنشاء مثيلات واجهة وظيفية (راجع توضيح الواجب الوظيفي):
1. تعبيرات لامدا
2. طريقة الاقتباس
3. مرجع طريقة المنشئ
لخص
ما سبق هو كل شيء عن هذا المقال حول فهم Java 8 البسيط لتعبيرات Lambda والواجهات الوظيفية. آمل أن يكون ذلك مفيدًا للجميع. يمكن للأصدقاء المهتمين الاستمرار في الرجوع إلى الموضوعات الأخرى ذات الصلة على هذا الموقع. إذا كانت هناك أي أوجه قصور ، فيرجى ترك رسالة لإشارةها!