Рубрики
Без рубрики

Опционально OrElse Опционально

Узнайте, как вернуть другой необязательный экземпляр, если первый экземпляр пуст.

Автор оригинала: Fatos Morina.

1. введение

В некоторых случаях мы можем захотеть вернуться к другому Необязательному экземпляру, если другой экземпляр пуст.

В этом уроке мы кратко расскажем, как мы можем это сделать, что сложнее, чем кажется.

Для ознакомления с необязательным классом Java ознакомьтесь с нашей предыдущей статьей .

2. Java 8

В Java 8 нет прямого способа добиться возврата другого Необязательный если первый из них пуст.

Поэтому мы можем реализовать ваш собственный пользовательский метод:

public static  Optional or(Optional optional, Optional fallback) {
    return optional.isPresent() ? optional : fallback;
}

И на практике:

@Test
public void givenOptional_whenValue_thenOptionalGeneralMethod() {
    String name = "Filan Fisteku";
    String missingOptional = "Name not provided";
    Optional optionalString = Optional.ofNullable(name);
    Optional fallbackOptionalString = Optional.ofNullable(missingOptional);
 
    assertEquals(
      optionalString, 
      Optionals.or(optionalString, fallbackOptionalString));
}
    
@Test
public void givenEmptyOptional_whenValue_thenOptionalGeneralMethod() {
    Optional optionalString = Optional.empty();
    Optional fallbackOptionalString = Optional.ofNullable("Name not provided");
 
    assertEquals(
      fallbackOptionalString, 
      Optionals.or(optionalString, fallbackOptionalString));
}

2.1. Ленивая оценка

Приведенное выше решение имеет один серьезный недостаток – нам нужно оценить обе Необязательные переменные перед использованием нашего пользовательского или() метода .

Представьте, что у нас есть два метода, возвращающих Необязательные s, оба запрашивают базу данных под капотом. С точки зрения производительности было бы неприемлемо вызывать их оба, если уже первый метод возвращает нужное нам значение.

Давайте создадим простой Поставщик элементов класс:

public class ItemsProvider {
    public Optional getNail(){
        System.out.println("Returning a nail");
        return Optional.of("nail");
    }

    public Optional getHammer(){
        System.out.println("Returning a hammer");
        return Optional.of("hammer");
    }
}

Вот как мы можем связать эти методы в цепочку и воспользоваться преимуществами ленивой оценки :

@Test
public void givenTwoOptionalMethods_whenFirstNonEmpty_thenSecondNotEvaluated() {
    ItemsProvider itemsProvider = new ItemsProvider();

    Optional item = itemsProvider.getNail()
            .map(Optional::of)
            .orElseGet(itemsProvider::getHammer);

    assertEquals(Optional.of("nail"), item);
}

Приведенный выше тестовый случай печатает только “Возврат гвоздя” . Это ясно указывает на то, что был выполнен только метод getNail () .

3. Java 9

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

Давайте посмотрим на это на практике с помощью краткого примера:

public static Optional getName(Optional name) {
    return name.or(() -> getCustomMessage());
}

Мы использовали вспомогательный метод, чтобы помочь нам с нашим примером:

private static Optional getCustomMessage() {
    return Optional.of("Name not provided");
}

Мы можем протестировать его и понять, как он работает. Следующий тестовый случай является демонстрацией случая, когда Необязательно имеет значение:

@Test
public void givenOptional_whenValue_thenOptional() {
    String name = "Filan Fisteku";
    Optional optionalString = Optional.ofNullable(name);
    assertEquals(optionalString, Optionals.getName(optionalString));
}

4. Использование Гуавы

Другой способ сделать это-использовать или() метод класса guava Optional . Во-первых, нам нужно добавить guava в наш проект (последнюю версию можно найти здесь ):


    com.google.guava
    guava
    24.1.1-jre

Теперь мы можем продолжить с тем же примером, что и ранее:

public static com.google.common.base.Optional 
  getOptionalGuavaName(com.google.common.base.Optional name) {
    return name.or(getCustomMessageGuava());
}
private static com.google.common.base.Optional getCustomMessageGuava() {
    return com.google.common.base.Optional.of("Name not provided");
}

Как мы видим, он очень похож на тот, что показан выше. Однако он имеет небольшое различие в именовании метода и точно такой же, как или() метод класса Необязательно из JDK 9.

Теперь мы можем проверить это, аналогично приведенному выше примеру:

@Test
public void givenGuavaOptional_whenInvoke_thenOptional() {
    String name = "Filan Fisteku";
    Optional stringOptional = Optional.of(name);
 
    assertEquals(name, Optionals.getOptionalGuavaName(stringOptional));
}
@Test
public void givenGuavaOptional_whenNull_thenDefaultText() {
    assertEquals(
      com.google.common.base.Optional.of("Name not provided"), 
      Optionals.getOptionalGuavaName(com.google.common.base.Optional.fromNullable(null)));
}

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

Это была краткая статья, иллюстрирующая, как достичь Необязательной или необязательной функциональности.

Код для всех примеров, описанных здесь, и многое другое можно найти на GitHub .