Stream API

در گروه منتشر شد
Stream API - 1

Stream API چیست؟

Stream API یک روش جدید برای کار با ساختارهای داده به سبک عملکردی است. جریان یک API (توضیح راه هایی که یک برنامه کامپیوتری می تواند با برنامه دیگر ارتباط برقرار کند) در هسته خود جریانی از داده است. خود اصطلاح "thread" در برنامه نویسی به طور کلی و در جاوا به طور خاص کاملاً مبهم است.
Stream API - 1
با ظهور جاوا 8، Stream API به برنامه نویسان این امکان را داد که به طور خلاصه تری بنویسند که قبلاً چندین خط کد را می طلبید، یعنی ساده کردن کار با مجموعه داده ها، به ویژه، ساده کردن فیلتر کردن، مرتب سازی و سایر عملیات دستکاری داده ها. اگر عملیات میانی ندارید، اغلب می‌توانید و باید بدون استریم انجام دهید، در غیر این صورت کد پیچیده‌تر از بدون جریان خواهد بود.
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);
	}
راه های ممکن برای ایجاد یک جریان:
Stream API - 3
  • جریان خالی:Stream.empty()
  • جریان از لیست:list.stream()
  • جریان از نقشه:map.entrySet().stream()
  • جریان از آرایه:Arrays.stream(array)
  • جریان از عناصر مشخص شده:Stream.of("1", "2", "3")
علاوه بر این، چیزی به نام عملگرها (اصولاً روش های کلاس Stream) وجود دارد. اپراتورها را می توان به دو گروه تقسیم کرد:
  • متوسط ​​(همچنین "تنبل" نامیده می شود) - عناصر ورودی را پردازش کنید و جریان را برگردانید. عملگرهای واسطه ای زیادی در زنجیره پردازش عناصر وجود دارد.
  • ترمینال ("ترمینال" که "اشتیاق" نیز نامیده می شود) - عناصر را پردازش کرده و جریان را خاتمه می دهد، بنابراین فقط یک اپراتور پایانه در زنجیره وجود دارد.
مثال:
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))که به نوبه خود از تمام عناصر مجموعه ارسال شده به آن عبور می کند و آن را نمایش می دهد)
Stream API - 5
نکات مهم:
  • تا زمانی که اپراتور ترمینال فراخوانی نشود، پردازش آغاز نخواهد شد. list.stream().filter(s -> s > 5)(یک عنصر را از لیست نمی گیرد)؛
  • یک نمونه از یک جریان را نمی توان بیش از یک بار استفاده کرد =( ;
  • Stream API - 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));
در مرحله بعد، اجازه دهید به چند عملگر میانی نگاه کنیم:
Stream API - 7
  • filter(Predicate 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));
  • skip (long n) – skip n عنصر:

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

  • sorted (مقایسه کننده مقایسه) - جریان را مرتب می کند (مرتب سازی مانند TreeMap):

    stream.sorted().forEach(x -> System.out.println(x));
  • distinct() - جریان را برای منحصر به فرد بودن عناصر بررسی می کند (تکرار عناصر را حذف می کند).

  • dropWhile (گزاره محمول) - از عناصری که شرط را برآورده می کنند (که در جاوا 9 ظاهر شد، رد می شود، رابط عملکردی Predicate<T> بررسی می کند که آیا برخی از شرایط برآورده شده است یا خیر. اگر برآورده شد، true برگردانده می شود. عبارت لامبدا یک شی از نوع را می گیرد. T به عنوان یک پارامتر:

    Predicate<Integer> isPositive = x -> x > 0;
           System.out.println(isPositive.test(3)); // true
           System.out.println(isPositive.test(-9)); // false
اپراتورهای ترمینال:
Stream API - 8
  • forEach (کنش مصرف کننده) - مشابه برای هر (Consumer<T> برخی از عملکردها را روی یک شی از نوع T بدون برگرداندن چیزی انجام می دهد).

  • count() – تعداد عناصر جریان را برمی‌گرداند:

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

  • collect (Collector Collector) – متد همه عناصر را در یک لیست، مجموعه یا مجموعه دیگری جمع آوری می کند، عناصر را بر اساس معیاری گروه بندی می کند، همه چیز را در یک رشته ترکیب می کند و غیره:

    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 accumulator) - تمام عناصر جریان را به یک شی تبدیل می کند (مجموع همه عناصر را محاسبه کنید، یا عنصر حداقل را پیدا کنید)، ابتدا شی 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)
    حداکثر اختیاری (مقایسه کننده مقایسه) عنصر حداقل/حداکثر را بر اساس مقایسه کننده پاس شده جستجو می کند.

  • findFirst()– اولین عنصر جریان را بیرون می کشد:

    Stream.of(1, 2, 3, 4, 9).findFirst();
  • allMatch(Predicate predicate)- اگر همه عناصر جریان شرط را برآورده کنند، مقدار true را برمی گرداند. اگر با عنصری مواجه شد که نتیجه فراخوانی تابع محمول نادرست باشد ، اپراتور اسکن عناصر را متوقف می کند و false را برمی گرداند :

    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)- اگر با گذراندن تمام عناصر جریان، هیچ یک از آنها شرایط را برآورده نکرده باشند، true بر می گردند 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 تبدیل می کند و مجموع را محاسبه می کند.

لینک های مفید: PS: خجالت نکشید که ما را لایک کنید ^ : ^
نظرات
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION