Подтвердить что ты не робот

Есть ли такой класс, как Необязательный, но для необязательных?

Удобно объявлять функции для сопоставления значений и их потребления, если они присутствуют.

В ситуации, когда у вас есть несколько обязательных объектов и несколько опций, я обнаруживаю, что я обертываю другие в Optional.of(обязательный), так что я могу использовать те же выражения для них, не записывая все это назад.

Food vegetables = Food.someVegetables();
Optional<Food> condiment = Food.someCondiment();
Optional<Food> spices = Food.someSpices();

condiment.map(prepare).ifPresent(putOnPlate);
spices.map(prepare).ifPresent(putOnPlate);

Но тогда мне не нравится этот код:

putOnPlate.accept(prepare.apply(vegetables));

поэтому я завершу его:

Optional.of(vegetables).map(prepare).ifPresent(putOnPlate);

Но это просто неправильно, потому что овощи (в этом примере) на самом деле необязательны. Они очень важны, и я просто дал каждому впечатление, что они являются необязательными.

Итак, мой вопрос: есть ли какой-то класс в java, например java.util.Mandatory, поэтому я могу написать:

Mandatory.of(vegetables).map(prepare).definitelyPresentSo(putOnPlate);
4b9b3361

Ответ 1

Да, есть такой API. Вы можете заменить

Optional.of(vegetables).map(prepare).ifPresent(putOnPlate);

с

Stream.of(vegetables).map(prepare).forEach(putOnPlate);

теперь приходится жить с тем, что одиночный элемент Stream является частным случаем потока произвольных элементов (включая возможный пустой поток).

Но вы можете обрабатывать все обязательные элементы сразу

Stream.of(mandatory1, mandatory2, mandatory3 /* etc */).map(prepare).forEach(putOnPlate);

Было бы даже возможно включать необязательные элементы, но это будет не так удобно, как должно быть, поскольку Optional.stream() будет вводится не до Java 9.

Ответ 2

Основная идея Optional - абстрагирование нулевой вероятности (избавление от нулевых проверок) и предоставление свободного API для работы с необязательными значениями.

В случае значения, которое всегда присутствует, нет ничего абстрактного (по крайней мере, ничего с практическим значением), поэтому в чистой Java нет таких инструментов.

В других функциональных языках у вас есть несколько "монадических" инструментов, таких как Optional, доступных для разных прецедентов. Если вы хотите привести их на Java, Javaslang, вероятно, лучшее место для просмотра. Вы можете найти там такие инструменты, как Option, Try, Lazy, Validation, Either, Future, Tuple и целые Collections API, которые позволяют кодировать аналогичным образом, описанным вами.

Ответ 3

Возможно, я ошибаюсь, но если вам не нравится использовать Optional, вы можете просто использовать Stream только одного объекта. Поэтому вместо

Optional.of(vegetables).map(prepare).ifPresent(putOnPlate);

вы можете просто использовать:

Stream.of(vegetables).map(prepare).forEach(putOnPlate); 

Результат будет идентичным. Оба метода будут бросать NPE, если овощи равны нулю.

Arrays.asList(10, null).forEach(value -> {
        Optional.of(value).map(x -> x.toString()).ifPresent(System.out::println);
        Stream.of(value).map(x -> x.toString()).forEach(System.out::println);
});

Безопасная версия NPE будет

 Optional.ofNullable(value).map(x -> x.toString()).ifPresent(System.out::println);
 Stream.of(value).filter(Objects::nonNull).map(x -> x.toString()).forEach(System.out::println);

Optional - это просто контейнер для объекта, который может содержать или не содержать ненулевое значение.

Ответ 4

Кажется, вы ищете тип @NonNull Food.