Автор оригинала: Fatos Morina.
1. введение
В некоторых случаях мы можем захотеть вернуться к другому Необязательному экземпляру, если другой экземпляр пуст.
В этом уроке мы кратко расскажем, как мы можем это сделать, что сложнее, чем кажется.
Для ознакомления с необязательным классом Java ознакомьтесь с нашей предыдущей статьей .
2. Java 8
В Java 8 нет прямого способа добиться возврата другого Необязательный если первый из них пуст.
Поэтому мы можем реализовать ваш собственный пользовательский метод:
public staticOptional 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"; OptionaloptionalString = 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 OptionalgetNail(){ 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(); Optionalitem = itemsProvider.getNail() .map(Optional::of) .orElseGet(itemsProvider::getHammer); assertEquals(Optional.of("nail"), item); }
Приведенный выше тестовый случай печатает только “Возврат гвоздя” . Это ясно указывает на то, что был выполнен только метод getNail () .
3. Java 9
Java 9 добавила метод или () , который мы можем использовать для получения Необязательного или другого значения, если этого Необязательного нет .
Давайте посмотрим на это на практике с помощью краткого примера:
public static OptionalgetName(Optional name) { return name.or(() -> getCustomMessage()); }
Мы использовали вспомогательный метод, чтобы помочь нам с нашим примером:
private static OptionalgetCustomMessage() { return Optional.of("Name not provided"); }
Мы можем протестировать его и понять, как он работает. Следующий тестовый случай является демонстрацией случая, когда Необязательно имеет значение:
@Test public void givenOptional_whenValue_thenOptional() { String name = "Filan Fisteku"; OptionaloptionalString = 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.OptionalgetOptionalGuavaName(com.google.common.base.Optional name) { return name.or(getCustomMessageGuava()); }
private static com.google.common.base.OptionalgetCustomMessageGuava() { return com.google.common.base.Optional.of("Name not provided"); }
Как мы видим, он очень похож на тот, что показан выше. Однако он имеет небольшое различие в именовании метода и точно такой же, как или() метод класса Необязательно из JDK 9.
Теперь мы можем проверить это, аналогично приведенному выше примеру:
@Test public void givenGuavaOptional_whenInvoke_thenOptional() { String name = "Filan Fisteku"; OptionalstringOptional = 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 .