Питання 25 · Розділ 8

Що таке операції anyMatch(), allMatch(), noneMatch()?

Три terminal-операції, які перевіряють елементи за предикатом і повертають boolean:

Мовні версії: English Russian Ukrainian

🟢 Junior Level

Три terminal-операції, які перевіряють елементи за предикатом і повертають boolean:

anyMatch(Predicate) — повертає true, якщо ХОЧА Б ОДИН елемент задовольняє умову:

boolean hasAdult = persons.stream()
    .anyMatch(p -> p.getAge() >= 18);

allMatch(Predicate) — повертає true, якщо ВСІ елементи задовольняють умову:

boolean allAdults = persons.stream()
    .allMatch(p -> p.getAge() >= 18);

noneMatch(Predicate) — повертає true, якщо ЖОДЕН елемент не задовольняє умову:

boolean noMinors = persons.stream()
    .noneMatch(p -> p.getAge() < 18);

Усі три використовують коротке замикання — зупиняються щойно результат стає очевидним.

anyMatch: зупиняється на ПЕРШОМУ збігу (true). allMatch: зупиняється на ПЕРШОМУ незбігу (false). noneMatch: зупиняється на ПЕРШОМУ збігу (false).

🟡 Middle Level

Алгоритм виконання

Еквівалент циклу з раннім виходом:

for (T element : source) {
    if (predicate.test(element)) {
        return true; // для anyMatch
    }
}

Завдяки ледачості, елементи запитуються по одному. При очевидному результаті конвеєр зупиняється.

Порівняння

Операція Зупинка Stream.empty()
anyMatch Перший true false
allMatch Перший false true
noneMatch Перший true true
// Порожній стрим:
// anyMatch() → false (немає елементів, збігів немає)
// allMatch() → true (vacuous truth — немає контрприкладів)
// noneMatch() → true (немає елементів, значить немає і збігів)

Vacuous Truth (Порожня істина)

Класичне запитання-пастка на інтерв’ю:

  • anyMatch на порожньому стримі → false (не знайшли жодного)
  • allMatch на порожньому стримі → true (умова виконана — елементів немає)
  • noneMatch на порожньому стримі → true (жоден не порушив)

🔴 Senior Level

Коли НЕ використовувати match-операції

  1. Потрібен сам елемент — використовуйте findFirst() / findAny()
  2. Потрібно знати скільки — використовуйте filter().count()
  3. Складна умова — якщо Predicate складний, краще filter() + читабельне ім’я методу

Parallelism через ShortCircuitTask

У паралельному режимі:

  • Кілька потоків перевіряють різні частини даних
  • При знаходженні “замикаючого” елемента подається сигнал Cancel усім задачам у ForkJoinPool
  • anyMatch у паралельному стримі дає величезний приріст на великих даних

Highload Context

Non-blocking: Відмінно для швидкої перевірки в реактивних системах.

Interference: Чутливі до зміни джерела під час виконання → ConcurrentModificationException.

Predicate Cost: Якщо предикат виконує важку роботу (запит у Redis), коротке замикання — головний союзник для мінімізації latency.

Діагностика

Early Exit Logging: Додайте peek() перед матчером — побачите тільки реально перевірені елементи.

Unit Testing: Завжди тестуйте на порожніх колекціях, враховуючи логіку allMatch/noneMatch, щоб уникнути помилок “порожньої істини”.


🎯 Шпаргалка для інтерв’ю

Обов’язково знати:

  • anyMatch — true якщо хоча б один елемент підходить (зупиняється на першому true)
  • allMatch — true якщо ВСІ елементи підходять (зупиняється на першому false)
  • noneMatch — true якщо ЖОДЕН елемент не підходить (зупиняється на першому true)
  • Усі три — terminal-операції з коротким замиканням
  • Порожній стрим: anyMatch → false, allMatch → true (vacuous truth), noneMatch → true
  • У паралельному режимі anyMatch дає величезний приріст на великих даних
  • Якщо потрібен сам елемент — використовуйте findFirst/findAny замість match-операцій

Часті уточнюючі запитання:

  • Чому allMatch на порожньому стримі повертає true? — Vacuous truth (порожня істина): немає контрприкладів, значить умова виконана для всіх (неіснуючих) елементів.
  • Чим anyMatch відрізняється від filter().findFirst()? — anyMatch повертає boolean і не створює Optional — менше overhead, якщо елемент не потрібен.
  • Чи працює коротке замикання у parallelStream? — Так, але менш ефективно — потоки отримують сигнал Cancel не миттєво.
  • Коли match-операції — поганий вибір? — Коли потрібен сам елемент, коли потрібна кількість, або коли предикат занадто складний для читабельності.

Червоні прапорці (НЕ говорити):

  • «anyMatch на порожньому стримі поверне true» — неправда, поверне false
  • «allMatch обробить всі елементи» — неправда, зупиняється на першому незбігу
  • «match-операції повертають елемент» — неправда, повертають тільки boolean
  • «noneMatch на порожньому стримі поверне false» — неправда, поверне true (vacuous truth)

Пов’язані теми:

  • [[24. Як працює коротке замикання (short-circuiting) в Stream]]
  • [[26. Що роблять операції findFirst() та findAny()]]
  • [[22. Коли починається виконання операцій в Stream]]
  • [[29. Як працювати з Optional в Stream]]