CodeGym /Kurslar /Java SELF AZ /Axınlarla iş, 3-cü hissə

Axınlarla iş, 3-cü hissə

Java SELF AZ
Səviyyə , Dərs
Mövcuddur

1. Yoxlama

Düşünürəm ki, artıq məlumat axınlarını necə quracağınızı öyrənməkdən darıxmısınız. Nəhayət, bu məlumatlarla nəsə etmək istəyirsiniz.

Stream sinifində üç standart metod var ki, onlar axınlar yaratmır, sadəcə bu axınlarda hansı məlumatların olduğunu yoxlayır. Bu metodlar: anyMatch(), allMatch()noneMatch().

boolean anyMatch(qayda) metodu

Bu metod axında qaydaya uyğun gələn ən azı bir elementin olub-olmadığını yoxlayır. Əgər belə bir element varsa, metod true qaytarır, əks halda — false.

Nümunələr

Kod Qeyd
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
boolean result = stream.anyMatch(x -> x > 0);

true
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.anyMatch(x -> x > 0);

true
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.filter(x -> x < 0).anyMatch(x -> x > 0);

false

Sonuncu nümunədə biz əvvəlcə sıfırdan kiçik bütün elementləri filtrdən keçiririk, sonra isə onların arasında sıfırdan böyük ən azı bir elementin olub-olmadığını yoxlayırıq. Təbii ki, belə elementlər artıq yoxdur.

Metod boolean allMatch(qayda)

Bu metod axındakı bütün elementlərin qaydaya uyğun olduğunu yoxlayır. Qayda metoda parametr kimi ötürülür:

Kod Qeyd
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
boolean result = stream.allMatch(x -> x > 0);
true
(bütün elementlər sıfırdan böyükdür)
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.allMatch(x -> x > 0);
false
(sıfır və ya sıfırdan kiçik elementlər var)
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.filter(x -> x < 0).allMatch(x -> x < 0);
true
(sıfırdan kiçik elementləri filtrdən keçirdik)

Sonuncu nümunədə biz əvvəlcə sıfırdan kiçik elementləri filtrdən keçiririk və sonra onların arasında bütün elementlərin sıfırdan kiçik olub-olmadığını yoxlayırıq. Yoxlama uğurla keçir.

Metod boolean noneMatch(qayda)

noneMatch() metodu axında qaydaya uyğun gələn heç bir elementin olmadığını yoxlayır. Məna baxımından bu metod anyMatch() metodunun əksidir.

Kod Qeyd
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
boolean result = stream.noneMatch(x -> x > 0);

false
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.noneMatch(x -> x > 0);

false
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.filter(x -> x < 0).noneMatch(x -> x > 0);

true


2. Köməkçi siniflər: Optional sinifi

Bəzən proqramçılar üçün null referansları ilə işləmək çox narahatedicidir. Məsələn, iki sətiri müqayisə edirsiniz. Hər iki dəyişən null deyilsə, asanlıqla s1.equals(s2) edə bilərsiniz və hər şey işləyəcək. Amma əgər s1 null ola bilsə, NullPointerException çıxmasın deyə bu vəziyyəti nəzərə alan kod yazmalısınız.

Proqramçılar buna görə köməkçi Optional<T> sinifini icad etdilər. Onun kodu təxminən belə görünür:

Kod Qeyd
class Optional<T>
{
   private final T value;
   private Optional() { this.value = null;}
   private Optional(value) { this.value = value;}
   public static <T> Optional<T> of(T value)
   {
      return new Optional<T>(value);
   }

   public boolean isPresent()
   {
      return value != null;
   }

   public boolean isEmpty()
   {
      return value == null;
   }

   public T get()
   {
      if (value == null)
      {
         throw new NoSuchElementException();
      }
      return value;
   }

   public T orElse(T other)
   {
      return value != null ? value : other;
   }

   public T orElseThrow()
   {
      if (value == null)
      {
         throw new NoSuchElementException();
      }
      return value;
   }
}










İçində dəyər (referans null deyil) olduğunu yoxlayır.



Obyektin null referansı saxladığını yoxlayır.




Saxladığı dəyəri qaytarır. Əgər dəyər yoxdursa, istisna atır.







Dəyəri qaytarır, əgər içindəki dəyər null olarsa, metoda ötürülən ikinci dəyəri qaytarır.



Dəyəri qaytarır, ya da dəyər yoxdursa, istisna atır.

Bu sinifin məqsədi sadəcə T obyektini (T tipində obyektin referansı) içində saxlamaqdır. Optional<T> sinifinin içində obyekt referansı null ola bilər.

Bu sinif proqramçılara biraz daha gözəl kod yazmağa imkan verir. Müqayisə edin:

Optional ilə Optional olmadan
public void printString(String s)
{
   Optional<String> str = Optional.ofNullable(s);
   System.out.println(str.orElse(""));
}
public void printString(String s)
{
   String str = s != null ? s : "";
   System.out.println(str)
}

Bir Optional obyektini həmişə başqa bir Optional obyekti ilə equals metodu vasitəsi ilə müqayisə etmək olar, hətta onların içindəki referanslar null olsa belə.

Başqa sözlə, Optional sinifi null üçün yoxlamaları və əgər içində null saxlanılırsa atılan addımları «daha gözəl» qeyd etmək üçün istifadə olunur.



3. Elementləri axtarış

Gəlin Stream sinfinə qayıdaq. Stream sinfinin axında elementləri axtarmağa imkan verən 4 metodu var. Bunlar findFirst(), findAny(), min()max() metodlarıdır.

Optional<T> findFirst() Metodu

findFirst() metodu sadəcə olaraq axından ilk elementi qaytarır və işi bundadır — vəssalam.

Daha maraqlısı budur ki, metod T tipi obyektini yox, onun üzərində obyekti qaytarır — Optional<T> obyektini. Bu onun üçündür ki, heç vaxt metodun obyekt tapmadığı və null qaytardığı vəziyyətlə qarşılaşmayasan.

Nümunə:

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Salam", "necəsən", "işlər?");
String str = list.stream().findFirst().get(); // Salam

Aydınlıq üçün son sətiri bir neçə sətirə aşağılamağa çalışaq:

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Salam", "necəsən", "işlər?");

Stream<String> stream = list.stream();
Optional<String> result = stream.findFirst();
String str = result.get(); // Salam

Sonuncu metod get(), sadəcə olaraq Optional obyektinin içərisində saxlanılan dəyəri çıxarmaq üçündür.

Optional<T> findAny() Metodu

findAny() metodu axından hər hansı elementi qaytarır və burada işi tamamlanır. Bu metod paralel işlənən axınlar üçün, findFirst() metodunun analoğudur.

Axınların paralel işləməsi zamanı belə vəziyyət ola bilər ki, axının hansısa hissəsində element artıq tapılıb, amma hələ məlum deyil, bu birinci olacaq ya yox.

Əgər bütün filtrlərdən keçən elementlər çoxdur və proqramçı üçün məhz birincisini əldə etmək vacibdirsə, findFirst() metodunu çağırmaq lazımdır. Əgər proqramçı dəqiq bilir ki, filtrdən keçən gerçəkdə 0 ya 1 element olacaqsa, sadəcə olaraq findAny() çağırmaq kifayətdir — belə daha sürətli olacaq.

Optional<T> min(Comparator<T>) Metodu

min() metodu bütün elementləri comparator obyekti ilə müqayisə edir və ən kiçik elementi qaytarır. Ən rahat Comparator obyektini lambda funksiyaları vasitəsilə təyin etməkdir.

Nümunə — ən qısa sətri tapmaq:

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Salam", "necəsən", "işlər?");
String min = list.stream().min( (s1, s2)-> s1.length()-s2.length() ).get();

Optional<T> max(Comparator<T>) Metodu

max() metodu bütün elementləri comparator obyekti ilə müqayisə edir və ən böyük elementi qaytarır. Ən rahat Comparator obyektini lambda funksiyaları vasitəsilə təyin etməkdir.

Nümunə — ən uzun sətri tapmaq:

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Salam", "necəsən", "işlər?");
String max = list.stream().max( (s1, s2)-> s1.length()-s2.length() ).get();
Şərhlər
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION