[Программирование, Java] Optional.stream() (перевод)

Автор Сообщение
news_bot ®

Стаж: 6 лет 3 месяца
Сообщений: 27286

Создавать темы news_bot ® написал(а)
08-Июн-2021 23:37


На этой неделе я узнал об одной интересной "новой" возможности Optional, о которой хочу рассказать в этом посте. Она доступна с Java 9, так что новизна ее относительна.Давайте начнем со следующей последовательности для вычисления общей цены заказа:
public BigDecimal getOrderPrice(Long orderId) {
    List<OrderLine> lines = orderRepository.findByOrderId(orderId);
    BigDecimal price = BigDecimal.ZERO;
    for (OrderLine line : lines) {
        price = price.add(line.getPrice());
    }
    return price;
}
  • Предоставьте переменную-аккумулятор для цены
  • Добавьте цену каждой строки к общей цене
В настоящее время, вероятно, более целесообразно использовать стримы вместо итераций. Следующий фрагмент эквивалентен предыдущему:
public BigDecimal getOrderPrice(Long orderId) {
    List<OrderLine> lines = orderRepository.findByOrderId(orderId);
    return lines.stream()
                .map(OrderLine::getPrice)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
}
Давайте сосредоточимся на переменной orderId : она может содержать null.Императивный способ обработки null заключается в том, чтобы проверить его в начале метода - и в конечном итоге сбросить:
public BigDecimal getOrderPrice(Long orderId) {
    if (orderId == null) {
        throw new IllegalArgumentException("Order ID cannot be null");
    }
    List<OrderLine> lines = orderRepository.findByOrderId(orderId);
    return lines.stream()
                .map(OrderLine::getPrice)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
}
Функциональный способ заключается в том, чтобы обернуть orderId в Optional. Вот как выглядит код с использованием Optional:
public BigDecimal getOrderPrice(Long orderId) {
    return Optional.ofNullable(orderId)
            .map(orderRepository::findByOrderId)
            .flatMap(lines -> {
                BigDecimal sum = lines.stream()
                        .map(OrderLine::getPrice)
                        .reduce(BigDecimal.ZERO, BigDecimal::add);
                return Optional.of(sum);
            }).orElse(BigDecimal.ZERO);
}
  • Оберните orderId в Optional
  • Найдите соответствующие строки заказа
  • Используйте flatMap(), чтобы получить Optional<BigDecimal>; map() получит Optional<Optional<BigDecimal>>
  • Нам нужно обернуть результат в Optional, чтобы он соответствовал сигнатуре метода.
  • Если Optional не содержит значения, сумма равна 0
Optional делает код менее читабельным! Я считаю, что понятность должна быть всегда важнее стиля кода.К счастью, Optional предлагает метод stream() (начиная с Java 9). Он позволяет упростить функциональный конвейер:
public BigDecimal getOrderPrice(Long orderId) {
    return Optional.ofNullable(orderId)
            .stream()
            .map(orderRepository::findByOrderId)
            .flatMap(Collection::stream)
            .map(OrderLine::getPrice)
            .reduce(BigDecimal.ZERO, BigDecimal::add);
}
Вот краткая информация о типе на каждой строке:
Функциональный код не обязательно означает то, что это также читаемый код. Учитывая последние изменения, я считаю, что это и то, и другое.
Перевод материала подготовлен в рамках курса "Java Developer. Basic". Приглашаем всех желающих на день открытых дверей онлайн, где можно подробнее узнать о формате и программе обучения, а также познакомиться с преподавателем.

===========
Источник:
habr.com
===========

===========
Автор оригинала: Nicolas Fränkel
===========
Похожие новости: Теги для поиска: #_programmirovanie (Программирование), #_java, #_java, #_java_development, #_api, #_functional_programming, #_optional, #_stream, #_blog_kompanii_otus (
Блог компании OTUS
)
, #_programmirovanie (
Программирование
)
, #_java
Профиль  ЛС 
Показать сообщения:     

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы

Текущее время: 10-Май 08:28
Часовой пояс: UTC + 5