Каким образом allSatisfy завершает обход Sequence, если условие впервые возвращает false?
allSatisfy немедленно прекращает обход после первого false и возвращает false. Если все проверенные элементы удовлетворили условию, обход продолжается до конца последовательности, после чего возвращается true.
Метод не создаёт промежуточную коллекцию. Поэтому он обычно экономнее, чем фильтрация всех элементов с последующей проверкой результата.
Функциональные операции над коллекциями появились как способ описывать преобразования и проверки через небольшие замыкания, не раскрывая детали ручного обхода. allSatisfy выражает проверку универсального условия: каждый ли элемент соответствует предикату.
Отдельный метод для такой проверки позволяет стандартной библиотеке использовать раннее завершение. Это решает проблему лишней обработки элементов, когда результат уже известен.
Предположим, приложение проверяет список объектов перед сохранением. Если один объект уже нарушает обязательное условие, проверять остальные необязательно.
Использование filter для такой задачи создаёт результат и обычно просматривает всю последовательность. Это увеличивает потребление памяти и время работы, а побочные эффекты внутри предиката могут выполниться для большего числа элементов, чем действительно нужно.
allSatisfy последовательно передаёт элементы в замыкание-предикат. После получения false метод сразу прекращает дальнейший вызов предиката и возвращает false; при отсутствии такого элемента он доходит до конца и возвращает true.
В примере будут проверены 2, 4 и 5, затем результатом станет false; значение 8 не проверяется. Для пустой последовательности результат равен true: в ней нет элемента, нарушающего условие.
Метод работает с Sequence, поэтому не требует случайного доступа и заранее известного размера. Если последовательность однопроходная, проверка может исчерпать её; повторный вызов не обязан дать тот же результат.
Предикат может иметь побочные эффекты, но полагаться на вызов для каждого элемента нельзя: при первом false последующие элементы не посещаются. Если нужен полный обход, следует выбрать операцию, семантика которой предполагает обработку всех элементов, либо выполнить явный обход.
Сервис проверяет, что все записи заказа имеют положительное количество. Вариант с фильтрацией создаёт массив ошибочных записей и продолжает обработку после первой ошибки. Вариант с reduce может выразить тот же итог, но менее явно и требует самостоятельно поддерживать логику остановки, тогда как обычный reduce не предназначен для раннего завершения.
Выбран allSatisfy: условие непосредственно отражает бизнес-правило, промежуточная коллекция не создаётся, а большой заказ прекращает проверку сразу после первой некорректной записи. Если одновременно требуется собрать все ошибки, этот вариант уже не подходит — нужен полный обход с накоплением результатов.
Какой результат даст allSatisfy для пустой последовательности?
Результат — true. Метод проверяет отсутствие нарушителей: поскольку элементов нет, ни один элемент не вернул false. Это соответствует логике универсального утверждения и важно учитывать при валидации пустых входных данных.
Что происходит, если предикат внутри allSatisfy выбрасывает ошибку?
Ошибка передаётся вызывающему коду, а дальнейший обход прекращается. Сигнатура метода позволяет это, поскольку операция объявлена как rethrows: она не добавляет собственных источников ошибок, но пробрасывает ошибку из переданного замыкания.
Почему allSatisfy может не завершиться на бесконечной последовательности?
Если бесконечная последовательность никогда не выдаёт элемент, для которого предикат возвращает false, методу некуда завершить проверку и он продолжит обход. Раннее завершение помогает только при обнаружении нарушения; для потенциально бесконечного источника нужен внешний лимит или другой механизм остановки.