Stream API

Guruhda nashr etilgan
Stream API - 1

Stream API nima?

Stream API - bu funktsional uslubda ma'lumotlar tuzilmalari bilan ishlashning yangi usuli. Stream API (bitta kompyuter dasturining boshqa dastur bilan bog‘lanish usullarining tavsifi) o‘zagida ma’lumotlar oqimidir. "Tread" atamasining o'zi umuman dasturlashda va xususan Java tilida juda noaniq.
Stream API - 1
Java 8 ning paydo bo'lishi bilan Stream API dasturchilarga ilgari ko'p qatorli kodlarni talab qilgan narsalarni qisqacha yozishga imkon berdi, xususan, ma'lumotlar to'plamlari bilan ishlashni soddalashtirish, xususan, filtrlash, saralash va boshqa ma'lumotlarni manipulyatsiya qilish operatsiyalarini soddalashtirish. Agar sizda oraliq operatsiyalar bo'lmasa, siz ko'pincha oqimsiz qilishingiz mumkin va kerak, aks holda kod oqimsiz ko'ra murakkabroq bo'ladi.
Stream API - 2
Qayerdan boshlashim kerak? Bizga kerak bo'lgan to'plam, massiv yoki usulga asoslangan Stream namunasini yaratishdan va shunga mos ravishda ma'lumotlar olinadigan joydan:
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();
Yuqorida aytib o'tilganidek, Stream API kod satrlari sonini kamaytirish imkonini beradi. Oqim bilan misol:
IntStream.of(50, 60, 70, 80, 90, 100, 110, 120).filter(x -> x < 90).map(x -> x + 10)
.limit(3).forEach(System.out::print);
Mavzusiz misol:
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 yaratishning mumkin bo'lgan usullari:
Stream API - 3
  • Bo'sh oqim:Stream.empty()
  • Roʻyxatdagi oqim:list.stream()
  • Xaritadan oqim:map.entrySet().stream()
  • Massivdan oqim:Arrays.stream(array)
  • Belgilangan elementlardan oqim:Stream.of("1", "2", "3")
Bundan tashqari, operatorlar (asosan Stream sinfining usullari) degan narsa mavjud.Operatorlarni ikki guruhga bo'lish mumkin:
  • Intermediate (shuningdek, "dangasa" deb ataladi) - kiruvchi elementlarni qayta ishlash va oqimni qaytarish. Elementlarni qayta ishlash zanjirida ko'plab oraliq operatorlar bo'lishi mumkin.
  • Terminal ("terminal", shuningdek, "ishtiyoqli" deb ham ataladi) - elementlarni qayta ishlaydi va oqimni to'xtatadi, shuning uchun zanjirda faqat bitta terminal operatori bo'lishi mumkin.
Misol:
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);
Bu erda nima bo'lyapti:
  • 1 - ro'yxat yaratish list;
  • 2-11 - uni test ma'lumotlari bilan to'ldirish;
  • 12 - ob'ekt yaratish Stream;
  • 13 - usul filter(filtr) - oraliq operator, xsanab o'tish uchun to'plamning bitta elementiga tenglashadi ( kabi for each) va ->dan keyin biz to'plamimiz qanday filtrlanganligini ko'rsatamiz va bu oraliq operator bo'lgani uchun filtrlangan to'plam usulga o'tadi. , forEachbu esa o'z navbatida sanab o'tishning terminal (yakuniy) analogidir for each( System.out::printlnQisqa ifoda:: x-> System.out.println(x)), u o'z navbatida unga o'tgan to'plamning barcha elementlaridan o'tadi va uni aks ettiradi)
Stream API - 5
Muhim nuqtalar:
  • Terminal operatori chaqirilmaguncha ishlov berish boshlanmaydi. list.stream().filter(s -> s > 5)(ro'yxatdan bitta element olinmaydi);
  • Oqim namunasidan bir martadan ortiq foydalanish mumkin emas =( ;
  • Stream API - 6

    Shuning uchun, har safar yangi:

    list.stream().filter(x-> x.toString().length() == 3).forEach(System.out::println);
    list.stream().forEach(x -> System.out.println(x));
  • Bitta oqimda ko'plab oraliq operatorlar chaqirilishi mumkin, faqat bitta terminal operatori mavjud:

    stream.filter(x-> x.toString().length() == 3).map(x -> x + " - the length of the letters is three").forEach(x -> System.out.println(x));
Keyin ba'zi oraliq operatorlarni ko'rib chiqamiz:
Stream API - 7
  • filter(Predicate predicate)oqimni filtrlaydi, faqat shartdan o'tuvchi elementlarni o'tkazadi (Predicate Java SE 8 paketiga qo'shilgan o'rnatilgan funktsional interfeysdir. “ true ” va “ falsejava.util.functionqiymatini tekshiradi );
  • map(Function mapper)har bir elementni o'zgartiradigan va uni keyinroq o'tkazib yuboradigan funktsiyani yaratishga imkon beradi (Funktsional interfeys Function<T,R>T tipidagi ob'ektdan R tipidagi ob'ektga o'tish funktsiyasini ifodalaydi)
  • flatMap(Function<T, Stream<R>> mapper)- bilan bo'lgani kabi map, ular ibtidoiy oqimga aylantirish uchun ishlatiladi.
Masalan, bir qator oqimlar (massivlar, ro'yxatlar va boshqalar) bilan ishlaganda ularni bitta oqimga (massiv, ro'yxat va boshqalar) aylantiradi [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);
mapU mavzular ro'yxatiga aylantirilganda (aniqrog'i mavzular <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);
ga nisbatan yana bir farq map, siz bitta elementni nolga, bitta yoki boshqa ko'plab elementlarga aylantirishingiz mumkin. Bitta elementni nol elementlarga aylantirish uchun siz null, yoki bo'sh oqimni qaytarishingiz kerak. Bitta elementga aylantirish uchun siz bitta elementdan oqimni qaytarishingiz kerak, masalan, orqali Stream.of(x). Bir nechta elementlarni qaytarish uchun siz ushbu elementlar bilan istalgan usulda oqim yaratishingiz mumkin. Xuddi shu flatMap usuli, lekin Double, Integer va Long uchun:
  • flatMapToDouble (funksiya xaritasi)
  • flatMapToInt (Funksiya xaritasi)
  • flatMapToLong(Funksiya xaritasi)
Taqqoslash uchun yana bir misol, flatMap:
Stream.of(2, 3, 0, 1, 3)
        .flatMapToInt(x -> IntStream.range(0, x))
        .forEach(System.out::print);// 010120012
  • IntStream.range(0,x) – oqimga 0 (shu jumladan) dan x (shu jumladan emas) gacha bo'lgan elementlarni chiqaradi;

    xarita:

    Stream.of(2, 3, 0, 1, 3)
            .map(x -> IntStream.range(0, x))
            .forEach(System.out::print);//list of streams (streams);
  • limit(long maxSize) - oqimni elementlar soni bilan cheklaydi:

    stream.limit(5).forEach(x -> System.out.println(x));
  • skip(long n) – n elementni o‘tkazib yuborish:

    stream.skip(3).forEach(x -> System.out.println(x));
  • tartiblangan()

  • saralangan (Komparator solishtiruvchisi) - oqimni tartiblaydi (TreeMap kabi saralash):

    stream.sorted().forEach(x -> System.out.println(x));
  • distinct() - oqimni elementlarning o'ziga xosligini tekshiradi (elementlarning takrorlanishini olib tashlaydi);

  • dropWhile(Predicate predicate) - shartni qanoatlantiradigan elementlarni o'tkazib yuboradi (java 9 da paydo bo'lgan, Predicate<T> funksional interfeysi ma'lum bir shart bajarilganligini tekshiradi. Agar bajarilgan bo'lsa, true qaytariladi. Lambda ifodasi ob'ektni oladi. parametr sifatida T ni kiriting:

    Predicate<Integer> isPositive = x -> x > 0;
           System.out.println(isPositive.test(3)); // true
           System.out.println(isPositive.test(-9)); // false
Terminal operatorlari:
Stream API - 8
  • forEach(Iste'molchi harakati) - har biri uchun o'xshash (Consumer<T> hech narsa qaytarmasdan T tipidagi ob'ektda ba'zi amallarni bajaradi);

  • count() - oqim elementlari sonini qaytaradi:

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

  • yig'ish(Kollektor kollektori) - usul barcha elementlarni ro'yxatga, to'plamga yoki boshqa to'plamga to'playdi, elementlarni qandaydir mezon bo'yicha guruhlaydi, hamma narsani satrga birlashtiradi va hokazo:

    List<String> list = Stream.of(One,Two,Three).collect(Collectors.toList());
  • collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner)— bilan bir xil, collect(collector)qulaylik uchun faqat parametrlar bo'linadi ( supplieryangi ob'ektlarni (konteynerlarni) etkazib beradi, masalan new ArrayList(), accumulatorkonteynerga element qo'shadi, combineroqim qismlarini birlashtiradi);

  • kamaytirish(T identifikatori, BinaryOperator akkumulyatori) - oqimning barcha elementlarini bitta ob'ektga aylantiradi (barcha elementlarning yig'indisini hisoblang yoki minimal elementni toping), avval ob'ekt identityva oqimning birinchi elementi olinadi, funksiya qo'llaniladi accumulatorva identityuning natijasi bo'ladi. Keyin qolgan elementlar uchun hamma narsa davom etadi.

    int sum = Stream.of(1, 2, 3, 4, 5).reduce(10, (acc, x) -> acc + x);// = 25
  • reduce(BinaryOperator accumulator)— yuqoridagi usul bilan bir xil, lekin birinchisi yo'q identity, bu oqimning birinchi elementi

    Optional min(Comparator comparator)
    Majburiy emas max(Comparator comparator) o'tkazilgan taqqoslash asosida minimal/maksimal elementni qidiradi;

  • findFirst()– oqimning birinchi elementini chiqaradi:

    Stream.of(1, 2, 3, 4, 9).findFirst();
  • allMatch(Predicate predicate)— agar oqimning barcha elementlari shartni qondirsa, true qiymatini qaytaradi. Agar predikat funksiyasini chaqirish natijasi noto'g'ri bo'lgan elementga duch kelsa , operator elementlarni skanerlashni to'xtatadi va false qaytaradi :

    Stream.of(1, 2, 3, 4, 9).allMatch(x -> x <= 7);//false
  • anyMatch(Predicate predicate)- agar oqimning kamida bitta elementi shartga javob bersa, true qiymatini qaytaradi predicate:

    Stream.of(1, 2, 3, 4, 9).anyMatch(x -> x >= 7);//true
  • noneMatch(Predicate predicate)- agar oqimning barcha elementlaridan o'tib, ularning hech biri shartni qondirmasa, haqiqiy bo'ladi predicate:

    Stream.of(1, 2, 3, 4, 9).noneMatch(x -> x >= 7);//false
Va nihoyat men ba'zi usullarni ko'rib chiqmoqchiman Collectors:
  • toList()- elementlarni to'playdi List:

    List<Integer> list = Stream.of(99, 2, 3).collect(Collectors.toList());
  • toSet()- elementlarni to'plamga to'playdi:

    Set<Integer> set = Stream.of(99, 2, 3).collect(Collectors.toSet());
  • counting()— Elementlar sonini hisoblaydi:

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

  • joining(CharSequence delimiter)

  • joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix)— elementlarni bir qatorga to‘playdi. Bundan tashqari, siz butun ketma-ketlik uchun ajratuvchi, shuningdek, prefiks va qo'shimchani belgilashingiz mumkin:

    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)- ob'ektlarni int/long/double ga aylantiruvchi va yig'indini hisoblaydigan kollektor.

Foydali havolalar: PS: bizni yoqtirishlar bilan boqishdan uyalmang ^ : ^
Izohlar
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION