تعرف على الـ Streams مع Java 8

Ammar AlTahhanمنذ 7 سنوات

59474d6a29855_Java8Streams-3alampro.png.a0d64eaa2614d9fc6262afd2f7af7d6a.png

 

بسم الله الرحمن الرحيم

السلام عليكم ورحمة الله وبركاته

 

في هذا الموضوع، سنستعرض الStreams، وهي عبارة عن API جديدة ورائعه تم اضافتها في التحديث الأخير للJava 8.

باستخدام الStreams، ستستطيع معالجة بيانات الCollections كأنك تقوم بعمل Query في احد الSQL databases، وذلك بطريقة تعريفية بسيطة دون الحاجة لكتابة Loop في كل مرة تريد معالجة البيانات لتخرج بنتيجة معينة (جمع عناصر الArrayList على سبيل المثال)، وذلك بكتابة سطر برمجي واحد فقط!

هناك ميزة أخرى أيضا للStreams، وهي امكانية تفعيل جميع أنوية المعالج لتسريع عملية تنفيذ البرنامج دون الحاجة الى كتابة سطر واحد من كلاس الThreads المزعج!

 

ما هو الStream؟                                             

سنذكر تاليا أهم سمات الStream في الجافا:

  • تسلسل عناصر: الStream هو عبارة عن تسلسل لعناصر يتم استخلاصها من أحد المصادر (Sources) -قد تكون Array أو ArrayList الخ-، حيث يقوم الStream بـ قراءة/معالجة بيانات هذه المصادر عند الحاجة فقط
  • المصادر: قد تكون Collection, Arrays, I/O
  • العمليات: يدعم الStream مجموعة من العمليات (أو methods) على سبيل المثال لا الحصر: filter, map, limit, reduce, find, match
  • تكرارات تلقائية: الStreams تدعم التكرارات التلقائية (Automatic Iterations)، أي كما قلنا سابقا، لن تكتب المزيد من الloops، كل ماعليك فعله هو كتابة سطر واحد باستعمال الStreams والجافا ستقوم بالباقي

 

إنشاء الStream                                               

في الجافا 8، هناك طريقتان لإنشاء Stream:

  • ()stream: ستنشئ ستريم تسلسلي مربوط بcollection، ولكن بدون الاستفادة من ميزة تعدد أنوية المعالج في التنفيذ
  • ()parallelStream: ستنشئ ستريم متوازي مربوط بcollection، مستفيدًا من ميزة تعدد أنوية المعالج في التنفيذ

مثال:


List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());

 

أهم ميثودز الStream                                         

()forEach:

هذه الميثود تعطيك امكانية المرور بجميع عناصر الستريم للقيام بعملية معينة، في المثال التالي سنقوم بطباعة 10 ارقام عشوائية باستخدام forEach:


Random random = new Random();
random.ints().limit(10).forEach(System.out::println);

()map:

بهذه الميثود تستخدم لربط كل عنصر بالستريم مع نتيجة خاصة به. في المثال التالي سنقوم بطباعة مربعات ارقام مميزة باستخدام map:


List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
//get list of unique squares
List<Integer> squaresList = numbers.stream().map( i -> i*i).distinct().collect(Collectors.toList());

()filter:

يتم استخدام هذه الميثود للتخلص من بعض عناصر الستريم بناء على شروط معينة، المثال التالي يقوم بطباعة عدد ال Strings الفارغة:


List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
//get count of empty string
int count = strings.stream().filter(string -> string.isEmpty()).count();

()limit:

هذه الميثود تستخدم للحد من حجم الستريم بدون أي شروط، في المثال التالي سنقوم بطباعة 10 ارقام عشوائية باستخدام  limit:


Random random = new Random();
random.ints().limit(10).forEach(System.out::println);

 ()sorted:

يتم استخدام هذه الميثود لترتيب الستريم، الكود التالي يظهر كيف تقوم بطباعة 10 ارقام عشوائية مرتبة:


Random random = new Random();
random.ints().limit(10).sorted().forEach(System.out::println);

 ( لاحظ كيف أنجزنا المهمة بسطر واحد فقط، تخيل لو أردت أن تقوم بطباعة 10 ارقام عشوائية مرتبة بالطريقة التقليدية! )

 

Parallel Processing:                                        

هذه هي الطريقة الثانية لإنشاء الستريم الموازي (استعمال جميع أنوية المعالج لتنفيذ البرنامج) كما هو مذكور بالأعلى:


List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
//get count of empty string
int count = strings.parallelStream().filter(string -> string.isEmpty()).count();

لاحظ أنك تستطيع التبديل بين الStream والparallelStream بسهولة تامة.

 

Collectors:                                                       

نستخدم الCollectors لجمع نتائج معالجة بيانات الستريم واعادتها على شكل List.


List<String>strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");

List<String> filtered = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.toList());
System.out.println("Filtered List: " + filtered);

String mergedString = strings.stream().filter(string -> !string.isEmpty()).collect(Collectors.joining(", "));
System.out.println("Merged String: " + mergedString);

 

 

في المثال التالي، سنقوم بعمل مقارنة بين الJava 7 والJava 8 في برنامج يقوم بضم الStrings غير الفارغة.

import java.util.*;

public class Java8StreamTest {
  
  public static void main(String[] args) {
    
    // Java 7 approach
      System.out.println("Using Java 7: ");
      List<String> strings = Arrays.asList("abc", "", "bc", "efg", "abcd","", "jkl");
      System.out.println("List: " +strings);
    
      StringBuilder stringBuilder = new StringBuilder();
      for (String string: strings) {
         if (!string.isEmpty()) {
            stringBuilder.append(string);
            stringBuilder.append(", ");
         }
      }
      String mergedString = stringBuilder.toString();
      System.out.println("Merged String: " + mergedString);
      
    
    // Java 8 approach
      System.out.println("Using Java 8: ");
      System.out.println("List: " +strings);
      mergedString = strings.stream().filter(string ->!string.isEmpty()).collect(Collectors.joining(", "));
      System.out.println("Merged String: " + mergedString);
      
  }
  
}

 

 

وهنا نصل الى ختام موضوعنا، أسأل الله لي ولكم التوفيق والسداد.

كلمات دليلية:
1
إعجاب
5451
مشاهدات
0
مشاركة
1
متابع
متميز
محتوى رهيب

التعليقات (0)

لايوجد لديك حساب في عالم البرمجة؟

تحب تنضم لعالم البرمجة؟ وتنشئ عالمك الخاص، تنشر المقالات، الدورات، تشارك المبرمجين وتساعد الآخرين، اشترك الآن بخطوات يسيرة !