Автор оригинала: 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";
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 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";
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.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";
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 .