Stream API

Qrupda dərc edilmişdir
Stream API - 1

Stream API nədir?

Stream API funksional üslubda məlumat strukturları ilə işləmək üçün yeni üsuldur. Stream API (bir kompüter proqramının digər proqramla əlaqə qura bilmə yollarının təsviri) əsas etibarilə məlumat axınıdır. "Mövzu" termini ümumiyyətlə proqramlaşdırmada və xüsusən Java-da olduqca qeyri-müəyyəndir.
Stream API - 1
Java 8-in meydana çıxması ilə Stream API proqramçılara əvvəllər çoxlu kod sətirləri götürənləri daha qısa şəkildə yazmağa, yəni məlumat dəstləri ilə işi sadələşdirməyə, xüsusən də filtrləmə, çeşidləmə və digər məlumatların manipulyasiya əməliyyatlarını sadələşdirməyə imkan verdi. Aralıq əməliyyatlarınız yoxdursa, siz tez-tez axın olmadan edə bilərsiniz və etməlisiniz, əks halda kod axınsız olduğundan daha mürəkkəb olacaq.
Stream API - 2
Tam olaraq haradan başlamalıyam? Bizə lazım olan kolleksiya, massiv və ya metoda əsaslanan və məlumatların müvafiq olaraq haradan alınacağına əsaslanan Stream instansiyasının yaradılmasından:
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();
Yuxarıda qeyd edildiyi kimi, Stream API sizə kod sətirlərinin sayını azaltmağa imkan verir. Bir axın ilə nümunə:
IntStream.of(50, 60, 70, 80, 90, 100, 110, 120).filter(x -> x < 90).map(x -> x + 10)
.limit(3).forEach(System.out::print);
Mövzusuz nümunə:
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);
	}
Axın yaratmağın mümkün yolları:
Stream API - 3
  • Boş yayım:Stream.empty()
  • Siyahıdan yayım:list.stream()
  • Xəritədən yayım:map.entrySet().stream()
  • Massivdən axın:Arrays.stream(array)
  • Göstərilən elementlərdən axın:Stream.of("1", "2", "3")
Bundan əlavə, operatorlar (əsasən Stream sinifinin metodları) kimi bir şey var.Operatorları iki qrupa bölmək olar:
  • Aralıq (həmçinin "tənbəl" adlanır) - daxil olan elementləri emal edir və axını qaytarır. Elementlərin emalı zəncirində çoxlu ara operatorlar ola bilər.
  • Terminal ("terminal", həmçinin "istəkli" adlanır) - elementləri emal edir və axını dayandırır, beləliklə zəncirdə yalnız bir terminal operatoru ola bilər.
Misal:
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);
Burda nə baş verir:
  • 1 - siyahı yaratmaq list;
  • 2-11 - test məlumatları ilə doldurun;
  • 12 - obyekt yaratmaq Stream;
  • 13 - metod filter(filtr) - aralıq operator, xsadalamaq üçün kolleksiyanın bir elementinə bərabərdir ( ilə kimi for each) və sonra -> biz kolleksiyamızın necə süzüldüyünü göstəririk və bu aralıq operator olduğundan, süzülmüş kolleksiya daha da irəli gedir. metod, forEachbu da öz növbəsində sadalamanın terminal (son) analoqudur for each(ifadə: System.out::printlnüçün qısadır, x-> System.out.println(x))bu da öz növbəsində ona ötürülən kolleksiyanın bütün elementlərindən keçir və onu göstərir)
Stream API - 5
Vacib məqamlar:
  • Terminal operatoru çağırılana qədər emal başlamayacaq. list.stream().filter(s -> s > 5)(siyahıdan heç bir element götürməyəcək);
  • Axın nümunəsi bir dəfədən çox istifadə edilə bilməz =( ;
  • Stream API - 6

    Buna görə də, hər dəfə yeni:

    list.stream().filter(x-> x.toString().length() == 3).forEach(System.out::println);
    list.stream().forEach(x -> System.out.println(x));
  • Yalnız bir terminal operatoru olduğu halda, bir axın üzrə çağırılan bir çox ara operator ola bilər:

    stream.filter(x-> x.toString().length() == 3).map(x -> x + " - the length of the letters is three").forEach(x -> System.out.println(x));
Sonra bəzi ara operatorlara baxaq:
Stream API - 7
  • filter(Predicate predicate)yalnız şərti keçən elementləri ötürərək axını filtrləyir (Predicate Java SE 8-də paketə əlavə edilmiş daxili funksional interfeysdir. “ true ” və “ falsejava.util.functiondəyərini yoxlayır );
  • map(Function mapper)hər bir elementi dəyişdirəcəyimiz və onu daha da atlayacağımız bir funksiya yaratmağa imkan verir (Funksional interfeys Function<T,R>T tipli obyektdən R tipli obyektə keçid funksiyasını təmsil edir)
  • flatMap(Function<T, Stream<R>> mapper)- ilə olduğu kimi map, onlar primitiv axına çevirmək üçün istifadə olunur.
Məsələn, bir sıra axınlar (massivlər, siyahılar və s.) ilə işləyərkən onları bir axına (massiv, siyahı və s.) çevirir [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);
mapMövzular siyahısına çevrilərkən (daha doğrusu mövzular <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);
ilə müqayisədə başqa bir fərq map, bir elementi sıfıra, birinə və ya bir çox başqasına çevirə bilərsiniz. nullBir elementi sıfır elementə çevirmək üçün , ya da boş bir axını qaytarmalısınız . Bir elementə çevirmək üçün bir elementdən axını qaytarmalısınız, məsələn, vasitəsilə Stream.of(x). Bir neçə elementi qaytarmaq üçün istənilən vasitə ilə bu elementlərlə axın yarada bilərsiniz. Eyni flatMap metodu, lakin Double, Integer və Long üçün:
  • flatMapToDouble(Funksiya mapper)
  • flatMapToInt(Funksiya xəritəçisi)
  • flatMapToLong(Funksiya xəritəçisi)
Müqayisə üçün başqa bir nümunə, flatMap:
Stream.of(2, 3, 0, 1, 3)
        .flatMapToInt(x -> IntStream.range(0, x))
        .forEach(System.out::print);// 010120012
  • IntStream.range(0,x) – axına 0 (daxil olmaqla) ilə x (daxil deyil) elementlərini çıxarır;

    xəritə:

    Stream.of(2, 3, 0, 1, 3)
            .map(x -> IntStream.range(0, x))
            .forEach(System.out::print);//list of streams (streams);
  • limit(long maxSize) – axını elementlərin sayına görə məhdudlaşdırır:

    stream.limit(5).forEach(x -> System.out.println(x));
  • skip(uzun n) – n elementi keçin:

    stream.skip(3).forEach(x -> System.out.println(x));
  • sıralanmış()

  • sorted(Müqayisəli müqayisəçi) – axını çeşidləyir (TreeMap kimi çeşidləmə):

    stream.sorted().forEach(x -> System.out.println(x));
  • distinct() — elementlərin unikallığı üçün axını yoxlayır (elementlərin təkrarlarını aradan qaldırır);

  • dropWhile(Predicate predicate) - şərti təmin edən elementləri ötür (java 9-da göründü, Predicate<T> funksional interfeysi müəyyən şərtin yerinə yetirilib-yetirilmədiyini yoxlayır. Əgər yerinə yetirilirsə, onda doğru qaytarılır. Lambda ifadəsi obyekti götürür. parametr kimi T yazın:

    Predicate<Integer> isPositive = x -> x > 0;
           System.out.println(isPositive.test(3)); // true
           System.out.println(isPositive.test(-9)); // false
Terminal operatorları:
Stream API - 8
  • forEach(Consumer action) – hər biri üçün analoji (Consumer<T> heç nə qaytarmadan T tipli obyektdə bəzi hərəkətləri yerinə yetirir);

  • count() – axın elementlərinin sayını qaytarır:

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

  • toplamaq(Kollektor kollektoru) – metod bütün elementləri siyahıda, dəstdə və ya digər kolleksiyada toplayır, elementləri hansısa meyarlara uyğun qruplaşdırır, hər şeyi sətirdə birləşdirir və s.:

    List<String> list = Stream.of(One,Two,Three).collect(Collectors.toList());
  • collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner)— ilə eyni, collect(collector)rahatlıq üçün yalnız parametrlər bölünür ( supplieryeni obyektlər (konteynerlər) verir, məsələn new ArrayList(), accumulatorkonteynerə element əlavə edir, combineraxının hissələrini birləşdirir);

  • azaltmaq(T şəxsiyyəti, BinaryOperator akkumulyatoru) - axının bütün elementlərini bir obyektə çevirir (bütün elementlərin cəmini hesablayın və ya minimum elementi tapın), əvvəlcə obyekt identityvə axının birinci elementi götürülür, funksiya tətbiq edilir accumulatoridentityonun nəticəsi olur. Sonra qalan elementlər üçün hər şey davam edir.

    int sum = Stream.of(1, 2, 3, 4, 5).reduce(10, (acc, x) -> acc + x);// = 25
  • reduce(BinaryOperator accumulator)— yuxarıdakı üsulla eynidir, lakin ilkin yoxdur identity, bu, axının ilk elementidir

    Optional min(Comparator comparator)
    Könüllü max(Müqayisəli müqayisə aparatı) keçən müqayisəçi əsasında minimum/maksimum elementi axtarır;

  • findFirst()– axının ilk elementini çıxarır:

    Stream.of(1, 2, 3, 4, 9).findFirst();
  • allMatch(Predicate predicate)— axının bütün elementləri şərti ödəyirsə, doğru qaytarır. Əgər predikat funksiyasının çağırılmasının nəticəsi false olan hər hansı elementə rast gəlinərsə , operator elementləri skan etməyi dayandırır və false qaytarır :

    Stream.of(1, 2, 3, 4, 9).allMatch(x -> x <= 7);//false
  • anyMatch(Predicate predicate)— axının ən azı bir elementi şərtə cavab verərsə, doğru qaytarılacaq predicate:

    Stream.of(1, 2, 3, 4, 9).anyMatch(x -> x >= 7);//true
  • noneMatch(Predicate predicate)- axının bütün elementlərini keçərək, onlardan heç biri şərti təmin etmədikdə doğru qayıdacaq predicate:

    Stream.of(1, 2, 3, 4, 9).noneMatch(x -> x >= 7);//false
Və nəhayət, bəzi üsullara baxmaq istərdim Collectors:
  • toList()- elementləri toplayır List:

    List<Integer> list = Stream.of(99, 2, 3).collect(Collectors.toList());
  • toSet()— elementləri çoxluğa toplayır:

    Set<Integer> set = Stream.of(99, 2, 3).collect(Collectors.toSet());
  • counting()— Elementlərin sayını hesablayır:

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

  • joining(CharSequence delimiter)

  • joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix)— elementləri bir sətirdə toplayır. Əlavə olaraq, bütün ardıcıllıq üçün ayırıcı, həmçinin prefiks və şəkilçi təyin edə bilərsiniz:

    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)- obyektləri int/long/double-a çevirən və cəmi hesablayan kollektor.

Faydalı bağlantılar: P.S: Bizi bəyənmələrlə duşməkdən utanmayın ^ : ^
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION