البرمجة الوظيفية في Java: من لامدا إلى Stream API

مدرب بايثون أونلاين للمبتدئين

تعلم Python بسهولة دون إرهاق نظري. حل مهام عملية مع التحقق التلقائي واكتب الكود مباشرة في المتصفح.

ابدأ الدورة

مقدمة في البرمجة الوظيفية في Java



لفترة طويلة، ارتبطت Java حصريًا بالبرمجة كائنية التوجه (OOP). ومع ذلك، مع إصدار Java 8 في عام 2014، حققت اللغة قفزة قوية نحو النموذج الوظيفي. لقد غيرت تعبيرات Lambda والواجهات الوظيفية و Stream API بشكل جذري طريقة كتابة الكود، مما جعله أكثر إيجازًا وقابلية للقراءة وأقل عرضة للأخطاء.



البرمجة الوظيفية في Java ليست بديلاً عن OOP، بل هي إضافة قوية. إنها تسمح بكتابة كود تصريحي، حيث تصف ماذا تريد أن تفعل، وليس كيف. في هذه المقالة، سنشرح المفاهيم الأساسية التي ستساعدك على إتقان الأسلوب الوظيفي في Java، وسنعرض أمثلة عملية.



1. تعبيرات Lambda والواجهات الوظيفية



أساس البرمجة الوظيفية في Java هو تعبيرات Lambda — وهي طريقة مدمجة لتنفيذ الدوال المجهولة. من الناحية التركيبية، يتكون Lambda من قائمة من المعاملات، وسهم (->)، وجسم:



(المعاملات) -> { الجسم }


تعمل تعبيرات Lambda دائمًا جنبًا إلى جنب مع الواجهات الوظيفية. الواجهة الوظيفية هي واجهة تحتوي على طريقة مجردة واحدة بالضبط (مثل Runnable، Comparator، Predicate).



مثال عملي: استبدال الفئة المجهولة



لنقارن بين الأسلوب القديم (OOP) والجديد (الوظيفي):



// الطريقة القديمة (فئة مجهولة)Runnable taskOld = new Runnable() {    @Override    public void run() {        System.out.println("مرحبًا من الفئة المجهولة!");    }};

// الطريقة الجديدة (Lambda)Runnable taskNew = () -> System.out.println("مرحبًا من Lambda!");

// التشغيلtaskNew.run();


كما ترى، قام Lambda بتقليل الكود من 6 أسطر إلى سطر واحد، مع الحفاظ على الوظائف الكاملة.



الواجهات الوظيفية المضمنة (حزمة java.util.function)



توفر Java مجموعة غنية من الواجهات المضمنة. إليك أربعة رئيسية:



  • Predicate<T> — تأخذ كائنًا، وتعيد boolean. تُستخدم للتصفية.
  • Function<T, R>
  • — تأخذ كائنًا من نوع، وتعيد كائنًا من نوع آخر. للتحويلات.
  • Consumer<T> — تأخذ كائنًا، ولا تعيد شيئًا (void). للتأثيرات الجانبية (الطباعة).
  • Supplier<T> — لا تأخذ شيئًا، وتعيد كائنًا. لتوليد البيانات البطيء (lazy).


مثال مع Predicate:



import java.util.function.Predicate;

public class Main { public static void main(String[] args) { Predicate<Integer> isEven = n -> n % 2 == 0; System.out.println(isEven.test(10)); // true System.out.println(isEven.test(7)); // false }}


2. Stream API: العمل مع المجموعات بأسلوب وظيفي



Stream API هي جوهرة البرمجة الوظيفية في Java. التدفق (Stream) هو سلسلة من العناصر تدعم العمليات المتسلسلة والمتوازية. الميزة الرئيسية: أنك لا تعدل البيانات الأصلية، بل تنشئ نتيجة جديدة.



يعتمد Stream API على ثلاث مراحل:

  1. إنشاء التدفق (من مجموعة، مصفوفة، أو مولد).
  2. العمليات الوسيطة (التصفية، الفرز، التحويل). تعيد Stream جديدًا.
  3. العملية النهائية (جمع النتيجة، العد، البحث). تنهي عمل التدفق.


مثال: تصفية وتحويل قائمة



لنفترض أن لدينا قائمة من السلاسل النصية، ونريد الحصول فقط على تلك التي يزيد طولها عن 3 أحرف، وتحويلها إلى أحرف كبيرة وفرزها.



import java.u                

المدونات

توصيات الكتب