دفق API

نشرت في المجموعة
واجهة برمجة التطبيقات للتدفق - 1

ما هو Stream API؟

تعد Stream API طريقة جديدة للعمل مع بنيات البيانات بأسلوب وظيفي. Stream An API (وصف للطرق التي يمكن لبرنامج كمبيوتر واحد من خلالها التواصل مع برنامج آخر) هو في جوهره تدفق من البيانات. مصطلح "خيط" في حد ذاته غامض تمامًا في البرمجة بشكل عام وفي Java بشكل خاص.
واجهة برمجة التطبيقات للتدفق - 1
مع ظهور Java 8، سمحت Stream API للمبرمجين بكتابة ما كان يتطلب في السابق العديد من أسطر التعليمات البرمجية بشكل أكثر إيجازًا، أي لتبسيط العمل مع مجموعات البيانات، على وجه الخصوص، لتبسيط عمليات التصفية والفرز وعمليات معالجة البيانات الأخرى. إذا لم يكن لديك عمليات وسيطة، فيمكنك في كثير من الأحيان الاستغناء عن التدفق، وإلا فسيكون الكود أكثر تعقيدًا من عدم وجود تدفق.
واجهة برمجة تطبيقات الدفق - 2
أين يجب أن أبدأ بالضبط؟ من إنشاء مثيل Stream، والذي يعتمد على المجموعة أو المصفوفة أو الطريقة التي نحتاجها ومن أين سيتم أخذ البيانات وفقًا لذلك:
List<String> list = new ArrayList<String>();
       list.add("One");
       list.add("Two");
       list.add("Three");
       list.add("Four");
       list.add("Five");
       list.add("Six");
       list.add("Seven");
       list.add("Eight");
       list.add("Nine");
       list.add("Ten");
       Stream stream = list.stream();
كما ذكرنا سابقًا، تتيح لك Stream API تقليل عدد أسطر التعليمات البرمجية. مثال مع دفق:
IntStream.of(50, 60, 70, 80, 90, 100, 110, 120).filter(x -> x < 90).map(x -> x + 10)
.limit(3).forEach(System.out::print);
مثال بدون موضوع:
int[] arr = {50, 60, 70, 80, 90, 100, 110, 120
	int count = 0;
	for (int x : arr) {
	    if (x >= 90) continue;
	    x += 10;
	    count++;
	    if (count > 3) break;
	    System.out.print(x);
	}
الطرق الممكنة لإنشاء دفق:
واجهة برمجة التطبيقات للبث - 3
  • تيار فارغ:Stream.empty()
  • الدفق من القائمة:list.stream()
  • التدفق من الخريطة:map.entrySet().stream()
  • التدفق من المصفوفة:Arrays.stream(array)
  • التدفق من العناصر المحددة:Stream.of("1", "2", "3")
علاوة على ذلك، هناك ما يسمى بالعوامل (وهي في الأساس أساليب لفئة الدفق)، ويمكن تقسيم العوامل إلى مجموعتين:
  • متوسط ​​(يسمى أيضًا "كسول") - يعالج العناصر الواردة ويعيد الدفق. يمكن أن يكون هناك العديد من العوامل الوسيطة في سلسلة معالجة العناصر.
  • المحطة ("المحطة"، وتسمى أيضًا "المحطة") - معالجة العناصر وإنهاء الدفق، بحيث لا يمكن أن يكون هناك سوى مشغل محطة واحد في السلسلة.
مثال:
1.List<String> list = new ArrayList<String>();
2.list.add("One");11.list.add("Ten");
12.Stream stream = list.stream();
13.stream.filter(x-> x.toString().length() == 3).forEach(System.out::println);
ما الذي يحدث هنا:
  • 1 - إنشاء قائمة list؛
  • 2-11 - املأها ببيانات الاختبار؛
  • 12 - إنشاء كائن Stream;
  • 13 - الطريقة filter(الفلتر) - عامل وسيط، xيعادل عنصرًا واحدًا من المجموعة للتعداد (كما هو الحال مع for each) وبعد -> نشير إلى كيفية تصفية مجموعتنا وبما أن هذا عامل وسيط، فإن المجموعة المفلترة تذهب أبعد من الطريقة ، forEachوالذي بدوره هو التناظرية النهائية (النهائية) للتعداد for each(تعبير System.out::printlnقصير لـ:، x-> System.out.println(x))والذي بدوره يمر عبر جميع عناصر المجموعة التي تم تمريرها إليها ويعرضها)
تيار API - 5
نقاط مهمة:
  • لن تبدأ المعالجة حتى يتم استدعاء مشغل المحطة. list.stream().filter(s -> s > 5)(لن يأخذ عنصرًا واحدًا من القائمة)؛
  • لا يمكن استخدام مثيل الدفق أكثر من مرة =( ;
  • واجهة برمجة تطبيقات الدفق - 6

    لذلك، في كل مرة يكون جديدًا:

    list.stream().filter(x-> x.toString().length() == 3).forEach(System.out::println);
    list.stream().forEach(x -> System.out.println(x));
  • يمكن أن يكون هناك العديد من المشغلين الوسيطين الذين يتم استدعاؤهم على تدفق واحد، بينما يوجد مشغل طرفي واحد فقط:

    stream.filter(x-> x.toString().length() == 3).map(x -> x + " - the length of the letters is three").forEach(x -> System.out.println(x));
بعد ذلك، دعونا نلقي نظرة على بعض العوامل الوسيطة:
تيار API - 7
  • filter(Predicate predicate)يقوم بتصفية الدفق، ويمرر فقط تلك العناصر التي تجتاز الشرط (المسند هو واجهة وظيفية مضمنة تضاف إلى الحزمة في Java SE 8. java.util.functionيتحقق من قيمة " صحيح " و" خطأ ")؛
  • map(Function mapper)يجعل من الممكن إنشاء وظيفة يمكننا من خلالها تغيير كل عنصر وتخطيه أكثر ( Function<T,R>تمثل الواجهة الوظيفية وظيفة الانتقال من كائن من النوع T إلى كائن من النوع R)
  • flatMap(Function<T, Stream<R>> mapper)- كما في حالة map, يتم استخدامها للتحويل إلى تيار بدائي.
عند العمل، على سبيل المثال، مع مصفوفة من التدفقات (المصفوفات، والقوائم، وما إلى ذلك)، فإنها تحولها إلى تدفق واحد (مصفوفة، وقائمة، وما إلى ذلك) [stream1,stream2,stream3,stream4] => stream:
String[] array = {"Java", "Ruuuuussshhh"};
Stream<String> streamOfArray = Arrays.stream(array);
streamOfArray.map(s->s.split("")) //Convert the word to an array of letters
        .flatMap(Arrays::stream).distinct() //aligns each generated thread into a single thread
        .collect(Collectors.toList()).forEach(System.out::println);
أثناء mapتحويله إلى قائمة المواضيع (بشكل أكثر دقة <Stream>المواضيع) [stream1,stream2,stream3,stream4] =>Stream.of(stream1,stream2,stream3,stream4):
String[] array = {"Java", "Ruuuuussshhh"};
Stream<String> streamOfArray = Arrays.stream(array);
streamOfArray.map(s->s.split("")) //Convert the word to an array of letters
        .map(Arrays::stream).distinct() //Make the array into a separate thread
        .collect(Collectors.toList()).forEach(System.out::println);
هناك اختلاف آخر مقارنة بـ map، حيث يمكنك تحويل عنصر واحد إلى صفر، أو عنصر واحد أو عدة عناصر أخرى. من أجل تحويل عنصر واحد إلى عناصر صفرية، تحتاج إلى العودة null، أو تيار فارغ. للتحويل إلى عنصر واحد، تحتاج إلى إرجاع دفق من عنصر واحد، على سبيل المثال، عبر Stream.of(x). لإرجاع عدة عناصر، يمكنك إنشاء دفق بهذه العناصر بأي وسيلة. نفس طريقة flatMap، لكن بالنسبة إلى Double وInteger وLong:
  • flatMapToDouble (مخطط الوظائف)
  • flatMapToInt (مخطط الوظائف)
  • flatMapToLong (مخطط الوظائف)
ومثال آخر للمقارنة، flatMap:
Stream.of(2, 3, 0, 1, 3)
        .flatMapToInt(x -> IntStream.range(0, x))
        .forEach(System.out::print);// 010120012
  • IntStream.range(0,x) - إخراج العناصر من 0 (شامل) إلى x (غير شامل) إلى الدفق؛

    خريطة:

    Stream.of(2, 3, 0, 1, 3)
            .map(x -> IntStream.range(0, x))
            .forEach(System.out::print);//list of streams (streams);
  • Limit(long maxSize) - يحد من الدفق بعدد العناصر:

    stream.limit(5).forEach(x -> System.out.println(x));
  • تخطي (طويل ن) - تخطي عناصر ن:

    stream.skip(3).forEach(x -> System.out.println(x));
  • مرتبة()

  • فرز (مقارنة المقارنة) - فرز الدفق (الفرز مثل TreeMap):

    stream.sorted().forEach(x -> System.out.println(x));
  • متميز () - يتحقق من تفرد العناصر في الدفق (يزيل تكرار العناصر) ؛

  • dropWhile (المسند المسند) - يتخطى العناصر التي تستوفي الشرط (ظهر في Java 9، تتحقق الواجهة الوظيفية Predicate<T> من استيفاء بعض الشروط. إذا تم استيفائه، فسيتم إرجاع true. يأخذ تعبير lambda كائنًا من النوع T كمعلمة:

    Predicate<Integer> isPositive = x -> x > 0;
           System.out.println(isPositive.test(3)); // true
           System.out.println(isPositive.test(-9)); // false
مشغلي المحطة:
ستريم API - 8
  • forEach(إجراء المستهلك) - مشابه لكل (المستهلك<T> ينفذ بعض الإجراءات على كائن من النوع T دون إرجاع أي شيء)؛

  • count() – يُرجع عدد عناصر الدفق:

    System.out.println(stream.count());

  • Collect (جامع المجمع) - الأسلوب يجمع كل العناصر في قائمة أو مجموعة أو مجموعة أخرى، ويجمع العناصر وفقًا لبعض المعايير، ويجمع كل شيء في سلسلة، وما إلى ذلك:

    List<String> list = Stream.of(One,Two,Three).collect(Collectors.toList());
  • collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner)- كما هو الحال في ، collect(collector)يتم تقسيم المعلمات فقط من أجل الراحة ( supplierتوفر كائنات جديدة (حاويات)، على سبيل المثال new ArrayList()، accumulatorتضيف عنصرًا إلى الحاوية، combinerوتجمع أجزاء من الدفق معًا)؛

  • تقليل (هوية T، مجمع BinaryOperator) - يحول جميع عناصر الدفق إلى كائن واحد (احسب مجموع كل العناصر، أو ابحث عن الحد الأدنى للعنصر)، أولاً identityيتم أخذ الكائن والعنصر الأول من الدفق، ويتم تطبيق الوظيفة accumulatorوتصبح identityنتيجته. ثم يستمر كل شيء بالنسبة للعناصر المتبقية.

    int sum = Stream.of(1, 2, 3, 4, 5).reduce(10, (acc, x) -> acc + x);// = 25
  • reduce(BinaryOperator accumulator)- نفس الطريقة المذكورة أعلاه ولكن الطريقة الأولية مفقودة identity، فهي العنصر الأول في الدفق

    Optional min(Comparator comparator)
    يبحث الحد الأقصى الاختياري (Comparator comparator) عن الحد الأدنى/الحد الأقصى للعنصر بناءً على المقارنة التي تم تمريرها؛

  • findFirst()- يسحب العنصر الأول من الدفق:

    Stream.of(1, 2, 3, 4, 9).findFirst();
  • allMatch(Predicate predicate)- يُرجع صحيحًا إذا كانت جميع عناصر الدفق تستوفي الشرط. إذا تمت مواجهة أي عنصر وكانت نتيجة استدعاء الدالة الأصلية خاطئة ، فسيتوقف المشغل عن فحص العناصر ويعيد خطأ :

    Stream.of(1, 2, 3, 4, 9).allMatch(x -> x <= 7);//false
  • anyMatch(Predicate predicate)- سيعود صحيحًا إذا استوفى عنصر واحد على الأقل من الدفق الشرط predicate:

    Stream.of(1, 2, 3, 4, 9).anyMatch(x -> x >= 7);//true
  • noneMatch(Predicate predicate)- سيعود صحيحًا إذا لم يستوفي أي منها الشرط، بعد المرور على جميع عناصر الدفق predicate:

    Stream.of(1, 2, 3, 4, 9).noneMatch(x -> x >= 7);//false
وأخيرا أود أن ألقي نظرة على بعض الأساليب Collectors:
  • toList()- يجمع العناصر في List:

    List<Integer> list = Stream.of(99, 2, 3).collect(Collectors.toList());
  • toSet()- يجمع العناصر في مجموعة:

    Set<Integer> set = Stream.of(99, 2, 3).collect(Collectors.toSet());
  • counting()- حساب عدد العناصر:

    Long count = Stream.of("1", "2", "3", "4").collect(Collectors.counting());
  • joining()

  • joining(CharSequence delimiter)

  • joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix)- يجمع العناصر في سطر واحد. بالإضافة إلى ذلك، يمكنك تحديد فاصل، بالإضافة إلى بادئة ولاحقة للتسلسل بأكمله:

    String a = Stream.of("s", "u" ,"p", "e", "r").collect(Collectors.joining());
           System.out.println(a); // super
    
           String b = Stream.of("s", "u", "p", "e", "r").collect(Collectors.joining("-"));
           System.out.println(b); // s-u-p-e-r
    
           String c = Stream.of("s", "u", "p", "e", "r").collect(Collectors.joining(" -> ", "[ ", " ]"));
           System.out.println(c);  // [ s -> u -> p -> e -> r ]
  • summingInt(ToIntFunction mapper)

  • summingLong(ToLongFunction mapper)

  • summingDouble(ToDoubleFunction mapper)- جامع يقوم بتحويل الكائنات إلى int/long/double ويحسب المجموع.

روابط مفيدة: ملاحظة: لا تخجل من إغراقنا بالإعجابات ^ : ^
تعليقات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION