Java 9 Необязательные дополнения API

Java 9 Необязательные дополнения API

1. обзор

В этой статье мы рассмотрим дополнения Java 9 к APIOptional.

Помимо модульности, Java 9 также добавляет три очень полезных метода для классаOptional.

2. Методor()

Иногда, когда нашOptional пуст, мы хотим выполнить какое-то другое действие, которое также возвращает Optional.

До Java 9 классOptional имел только методыorElse() иorElseGet(), но оба должны возвращать развернутые значения.

Java 9 представляет методor(), который лениво возвращает другойOptional, если нашOptional пуст. Если наш первыйOptional имеет определенное значение, лямбда, переданная методуor(), не будет вызвана, и значение не будет вычислено и возвращено:

@Test
public void givenOptional_whenPresent_thenShouldTakeAValueFromIt() {
    //given
    String expected = "properValue";
    Optional value = Optional.of(expected);
    Optional defaultValue = Optional.of("default");

    //when
    Optional result = value.or(() -> defaultValue);

    //then
    assertThat(result.get()).isEqualTo(expected);
}

В случае еслиOptional being пуст, возвращаемыйresult будет таким же, какdefaultValue:

@Test
public void givenOptional_whenEmpty_thenShouldTakeAValueFromOr() {
    // given
    String defaultString = "default";
    Optional value = Optional.empty();
    Optional defaultValue = Optional.of(defaultString);

    // when
    Optional result = value.or(() -> defaultValue);

    // then
    assertThat(result.get()).isEqualTo(defaultString);
}

3. МетодifPresentOrElse()

Когда у нас есть экземплярOptional, часто мы хотим выполнить определенное действие с его базовым значением. С другой стороны, еслиOptional равенempty, мы хотим зарегистрировать его или отслеживать этот факт, увеличивая некоторую метрику.

МетодifPresentOrElse() создан именно для таких сценариев. Мы можем передатьConsumer, который будет вызываться, еслиOptional определен, иRunnable, который будет выполнен, еслиOptional пуст.

Допустим, у нас есть определенныйOptional, и мы хотим увеличить конкретный счетчик, если значение присутствует:

@Test
public void givenOptional_whenPresent_thenShouldExecuteProperCallback() {
    // given
    Optional value = Optional.of("properValue");
    AtomicInteger successCounter = new AtomicInteger(0);
    AtomicInteger onEmptyOptionalCounter = new AtomicInteger(0);

    // when
    value.ifPresentOrElse(
      v -> successCounter.incrementAndGet(),
      onEmptyOptionalCounter::incrementAndGet);

    // then
    assertThat(successCounter.get()).isEqualTo(1);
    assertThat(onEmptyOptionalCounter.get()).isEqualTo(0);
}

Обратите внимание, что обратный вызов, переданный в качестве второго аргумента, не был выполнен.

В случае пустогоOptional, выполняется второй обратный вызов:

@Test
public void givenOptional_whenNotPresent_thenShouldExecuteProperCallback() {
    // given
    Optional value = Optional.empty();
    AtomicInteger successCounter = new AtomicInteger(0);
    AtomicInteger onEmptyOptionalCounter = new AtomicInteger(0);

    // when
    value.ifPresentOrElse(
      v -> successCounter.incrementAndGet(),
      onEmptyOptionalCounter::incrementAndGet);

    // then
    assertThat(successCounter.get()).isEqualTo(0);
    assertThat(onEmptyOptionalCounter.get()).isEqualTo(1);
}

4. Методstream()

Последний метод, добавленный к классуOptional в Java 9, - это методstream().

Java имеет очень плавный и элегантный APIStream, который может работать с коллекциями и использует многие концепции функционального программирования. Последняя версия Java представляет методstream() в классеOptional, которыйallows us to treat the Optional instance as a Stream.

Допустим, у нас есть определенныйOptional, и мы вызываем для него методstream(). Это создастStream одного элемента, для которого мы сможем использовать все методы, доступные вStream API:

@Test
public void givenOptionalOfSome_whenToStream_thenShouldTreatItAsOneElementStream() {
    // given
    Optional value = Optional.of("a");

    // when
    List collect = value.stream().map(String::toUpperCase).collect(Collectors.toList());

    // then
    assertThat(collect).hasSameElementsAs(List.of("A"));
}

С другой стороны, еслиOptional отсутствует, вызов для него методаstream() создаст пустойStream:

@Test
public void givenOptionalOfNone_whenToStream_thenShouldTreatItAsZeroElementStream() {
    // given
    Optional value = Optional.empty();

    // when
    List collect = value.stream()
      .map(String::toUpperCase)
      .collect(Collectors.toList());

    // then
    assertThat(collect).isEmpty();
}

Теперь мы можем быстро отфильтроватьStreams of Optionals.

Работа с пустымStream не будет иметь никакого эффекта, но благодаря методуstream() теперь мы можем связать APIOptional с APIStream. Это позволяет нам создавать более элегантный и свободный код.

5. Заключение

В этой быстрой статье мы рассмотрели дополнения к API Java 9Optional.

Мы увидели, как использовать методor() для возврата Optional в случае, если источникOptional пуст. Мы использовалиifPresentOrElse() для выполненияConsumer, если значение присутствует, а в противном случае - для выполнения другого обратного вызова.

Наконец, мы увидели, как связатьOptional с APIStream, используя методstream().

Реализация всех этих примеров и фрагментов кода можно найти вGitHub project - это проект Maven, поэтому его должно быть легко импортировать и запускать как есть.