JavaRush /Курстар /All lectures for KK purposes /Ағындармен жұмыс, 3-бөлім

Ағындармен жұмыс, 3-бөлім

All lectures for KK purposes
Деңгей , Сабақ
Қол жетімді

1. Тексеру

Ойлаймын, деректер ағындарын қалай құрастыруды үйренуден жалыққан шығарсыздар. Ақырында осы деректермен бірдеңе жасағыңыз келеді.

Stream класста үш стандартты әдіс бар, олар ағындарды құрастырмайды, ағындарда қандай деректер барын тексереді. Бұл әдістер: anyMatch(), allMatch() және noneMatch().

boolean anyMatch(ереже) әдісі

Бұл әдіс ағын ішіндегі кем дегенде бір элементтің ережеге сәйкес келе ме, жоқ па екенін тексереді. Егер ондай элемент болса, әдіс true қайтарады, әйтпесе — false.

Мысалдар

Код Түсініктеме
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

Соңғы мысалда біз алдымен барлық нөлден аз элементтерді сүзіп, одан кейін солардың арасында нөлден үлкен элемент бар ма екенін тексереміз. Әрине, ондай элементтер жоқ.

Метод boolean allMatch(ереже)

Бұл әдіс ағын ішіндегі барлық элементтердің ережеге сәйкес келе ме екенін тексереді. Ереже әдістің параметрі ретінде беріледі:

Код Түсініктеме
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5);
boolean result = stream.allMatch(x -> x > 0);
true
(барлық элементтер нөлден үлкен)
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.allMatch(x -> x > 0);
false
(нөлге тең немесе кем элементтер бар)
Stream<Integer> stream = Stream.of(1, -2, 3, -4, 5);
boolean result = stream.filter(x -> x < 0).allMatch(x -> x < 0);
true
(нөлден кем элементтерді сүздік)

Соңғы мысалда біз алдымен нөлден кем элементтерді сүздік, содан кейін олардың барлығының нөлден кем екенін тексереміз. Тексеріс сәтті өтеді.

Метод boolean noneMatch(ереже)

noneMatch() әдіс ағын ішіндегі ешбір элементтің ережеге сәйкес келмеуін тексереді. Ол мағынасы бойынша anyMatch() әдісіне қарама-қарсы келеді.

Код Түсініктеме
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. Көмекші класстар: Optional классы

Кейде программистерге null сілтемелерімен жұмыс істеу өте ыңғайсыз. Мысалы, екі жолды салыстырасыз. Егер екі айнымалы да null болмаса, онда s1.equals(s2) шақыру арқылы бәрі жұмыс істейді. Бірақ егер s1 null болуы мүмкін болса, NullPointerException пайда болмас үшін осы жағдайды ескеретін код жазуға тура келеді.

Сондықтан программистер Optional<T> көмегімен әлгілі бір класс ойлап тапты. Оның коды шамамен былайша көрінеді:

Код Түсініктеме
class Optional<Тип>
{
   private final Тип value;
   private Optional() { this.value = null;}
   private Optional(value) { this.value = value;}
   public static <Тип> Optional<Тип> of(Тип value)
   {
      return new Optional<Тип>(value);
   }

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

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

   public Тип get()
   {
      if (value == null)
      {
         throw new NoSuchElementException();
      }
      return value;
   }

   public Тип orElse(Тип other)
   {
      return value != null ? value : other;
   }

   public Тип orElseThrow()
   {
      if (value == null)
      {
         throw new NoSuchElementException();
      }
      return value;
   }
}










Ішінде мән бар (сілтеме null емес) екенін тексереді



Объекттің null сілтеме сақтағанын тексереді




Сақталған мәнді қайтарады. Егер мән жоқ болса, ерекше жағдайды лақтырады.







Мәнді қайтарады, немесе ішіндегі null болса, әдіске берілген екінші мәнді қайтарады



Мәнді қайтарып, егер мәні болмаса, ерекше жағдайды лақтырады.

Бұл класстың мақсаты – объект T (тип T объектіне сілтемені) сақтауға арналған. Optional<T> классының ішінде объектке сілтеме null болуы мүмкін.

Бұл класс программистерге кодты сәл әдемірек жазуға мүмкіндік береді. Салыстырыңыз:

Optional қолдану арқылы Optional қолданбай
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)
}

Бір Optional объектісін әрқашан басқа Optional объектісімен equals әдісі арқылы салыстыруға болады, тіпті олар null сілтемелер сақтаған кезде де.

Шамамен айтқанда, Optional класы олардың null сақтаған кездегі тексерістер мен әрекеттерді "әдемірек" жазуға мүмкіндік береді.



3. Элементтерді іздеу

Кері оралсақ Stream классына. Stream классында тағы 4 әдіс бар, олар ағын ішіндегі элементтерді іздеуге мүмкіндік береді. Бұл әдістер findFirst(), findAny(), min() және max().

Метод Optional<T> findFirst()

findFirst() әдісі тек ағынның бірінші элементін қайтарады және оның жұмысы аяқталады.

Ең қызығы, бұл әдіс T типіндегі объектіні қайтармайды, оның орнына — Optional<T> типіндегі объектіні қайтарады. Бұл ешқашан әдіс объектіні таппайтын және null қайтаратын жағдайға тап болмауы үшін жасалған.

Мысал:

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Сәлем", "қалайсың", "хал қалай?");
String str = list.stream().findFirst().get(); // Сәлем

Бұл соңғы жолды түсініктірек болу үшін бірнеше жолға жазайық:

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Сәлем", "қалайсың", "хал қалай?");

Stream<String> stream = list.stream();
Optional<String> result = stream.findFirst();
String str = result.get(); // Сәлем

Соңғы get() әдісі — бұл Optional объектісінің ішінде сақталған мәнді алу ғана.

Метод Optional<T> findAny()

findAny() әдісі ағын ішіндегі кез келген элементті қайтарады және жұмысы осымен аяқталады. Бұл әдіс параллельді өңделетін ағындарға арналған findFirst() әдісінің аналогы.

Ағындарды параллель өңдеу жағдайында ағынның бір бөлігінде элемент табылды деуге болады, бірақ ол бірінші немесе жоқ екені белгісіз.

Егер барлық фильтрлерден өтетін элементтер көп болса және программистке олардың ішінде біріншісін алу маңызды болса, онда findFirst() әдісін қолдану керек. Егер программист біледі, барлық фильтрлерден 0 немесе 1 элемент өтеді деп, тек findAny() әдісін қолдана салу жеткілікті — бұл тезірек болады.

Метод Optional<T> min(Comparator<T>)

min() әдісі ағын ішіндегі барлық элементтерді comparator объектісі арқылы салыстырады және ең кішісін қайтарады. Объект-компараторды лямбда-функция арқылы беруден ыңғайлырақ нәрсе жоқ.

Мысал — ең қысқа жолды іздеу:

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Сәлем", "қалайсың", "хал қалай?");
String min = list.stream().min( (s1, s2)-> s1.length()-s2.length() ).get();

Метод Optional<T> max(Comparator<T>)

max() әдісі ағын ішіндегі барлық элементтерді comparator объектісі арқылы салыстырады және ең үлкенін қайтарады. Объект-компараторды лямбда-функция арқылы беру қолайлы.

Мысал — ең ұзын жолды іздеу:

ArrayList<String> list = new ArrayList<String>();
Collections.addAll(list, "Сәлем", "қалайсың", "хал қалай?");
String max = list.stream().max( (s1, s2)-> s1.length()-s2.length() ).get;
Пікірлер
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION