Часто мы пишем код, чтобы выработать первый ответ из множества доступных. Давайте посмотрим на это в Java.
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
 | 
public Widget getAppropriateWidget(CustomerRequest request) {    if (shelfstock.contains(request.getBarcode()) {        return new ShelfWidget();    }    if (backroomStock.contains(request.getBarcode()) {        return new BackroomWidget();    }    if (supplier.contains(request.getEan()) {        return new SupplierWidget();    }    return null;} | 
Вам придется представить более сложный сценарий, скрывающийся за упрощенным кодом, описанным выше. Этот алгоритм пробует опции в порядке приоритета, пока не найдет работающий или не работает, и в этом случае он ничего не возвращает.
Давайте также представим, что вызовы содержимого по какой-то причине дороги — возможно, каждый из этих объектов скрывает веб-сервис или сложный запрос к базе данных.
  Давайте начнем с рефакторинга приведенного выше кода двумя способами.  Давайте сделаем так, чтобы он использовал Optional , и давайте заставим его использовать подпрограммы для каждого из методов. 
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
 | 
public Optional<Widget> getAppropriateWidget(CustomerRequest request) {    Optional<Widget> shelfWidget =         getShelfWidget(request);    if (shelfWidget.isPresent()) {        return shelfWidget;    }    Optional<Widget> backroomWidget =         getBackroomWidget(request);    if (backroomWidget.isPresent()) {        return backroomWidget;    }    Optional<Widget> supplierWidget =         getSupplierWidget(request);    if (supplierWidget.isPresent()) {        return supplierWidget;    }    return Optional.empty;}// imagine the subsidiary functions | 
  Таким образом, это лучше, чем null , так как возвращаемое значение not found, и старается изо всех сил использовать подпрограммы, чтобы эта функция описывала себя, но возникает проблема с тем фактом, что каждый из возвращаемых Optional объектов не может быть связан в цепь ответственности. 
Мы могли бы обмануть:
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
 | 
Optional<Widget> shelfWidget = getShelfWidget(request);Optional<Widget> backroomWidget = getBackroomWidget(request);Optional<Widget> supplierWidget = getSupplierWidget(request);return firstNonEmpty(shelfWidget, backroomWidget, supplierWidget);private static Optional<Widget> firstNonEmpty(            Optional<Widget> ... options) {    return Arrays.stream(options)        .filter(Optional::isPresent)        .findFirst() // makes an optional of optional here...        .orElse(Optional.empty());} | 
Приведенный выше код выглядит лучше, но теперь необходимо предварительно рассчитать все возможные ответы, прежде чем выбрать один. Мы должны быть в состоянии избежать дорогостоящего расчета варианта, если ответ будет доступен раньше.
Первое прошлое сообщение с дополнительным решением
Передайте поток или массив varargs в функцию, состоящую из объектов, которые предоставят необязательный. Если кто-то из них поставляет непустой, он побеждает.
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
 | 
// calling codepublic Optional<Widget> getAppropriateWidget(CustomerRequest request) {    return firstAvailable(() -> getShelfWidget(request),        () -> getBackroomWidget(request),        () -> getSupplierWidget(request));}// this is a general purpose solution// feel free to use it@SafeVarargsprivate static <T> Optional<T> firstAvailable(        Supplier<Optional<T>> ... options) {    return Arrays.stream(options)            .map(Supplier::get)            .filter(Optional::isPresent)            .findFirst()            .orElse(Optional.empty());} | 
| 
 Смотрите оригинальную статью здесь: First Past the Post Мнения, высказанные участниками Java Code Geeks, являются их собственными.  |