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.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ı:
- 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")
- 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.
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,x
sadalamaq üçün kolleksiyanın bir elementinə bərabərdir ( ilə kimifor 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,forEach
bu da öz növbəsində sadalamanın terminal (son) analoqudurfor 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)
- 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 =( ;
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));
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ə “ false ”java.util.function
də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 interfeysFunction<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 kimimap
, onlar primitiv axına çevirmək üçün istifadə olunur.
[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
Mö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. null
Bir 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)
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
-
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 (supplier
yeni obyektlər (konteynerlər) verir, məsələnnew ArrayList()
,accumulator
konteynerə element əlavə edir,combiner
axı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
identity
və axının birinci elementi götürülür, funksiya tətbiq ediliraccumulator
vəidentity
onun 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 yoxduridentity
, bu, axının ilk elementidirOptional 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ılacaqpredicate
: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ıdacaqpredicate
:Stream.of(1, 2, 3, 4, 9).noneMatch(x -> x >= 7);//false
Collectors
:
-
toList()
- elementləri toplayırList
: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.
GO TO FULL VERSION