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

Java Необязательно – OrElse() vs orElseGet()

Исследуйте различия между необязательными методами OrElse() и orElseGet ().

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

1. введение

API Необязательно обычно имеет два метода, которые могут вызвать путаницу: или Еще() и или еще Get() .

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

2. Подписи

Давайте сначала начнем с основ, посмотрев на их подписи:

public T orElse(T other)

public T orElseGet(Supplier other)

Очевидно, что or Else() принимает любой параметр типа T , тогда как orElseGet() принимает функциональный интерфейс типа Supplier , который возвращает объект типа T .

Теперь, основываясь на их Javadocs :

  • or Else() : возвращает значение, если оно присутствует, в противном случае возвращает другое
  • или же Get(): возвращает значение, если оно присутствует, в противном случае вызовите другое и верните результат его вызова

3. Различия

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

3.1. Орел()

Предполагая, что наш регистратор настроен правильно, давайте начнем с написания простого фрагмента кода:

String name = Optional.of("baeldung")
  .orElse(getRandomName());

Обратите внимание, что getRandomName () – это метод, который возвращает случайное имя из списка имен :

public String getRandomName() {
    LOG.info("getRandomName() method - start");
    
    Random random = new Random();
    int index = random.nextInt(5);
    
    LOG.info("getRandomName() method - end");
    return names.get(index);
}

При выполнении нашего кода мы найдем ниже сообщения, напечатанные в консоли:

getRandomName() method - start
getRandomName() method - end

Переменная name будет содержать “baeldung” в конце выполнения кода.

С его помощью мы можем легко сделать вывод, что параметр из or Else() вычисляется даже при наличии непустого Необязательного .

3.2. орЕлсеГет()

Теперь давайте попробуем написать аналогичный код с помощью или Get() :

String name = Optional.of("baeldung")
  .orElseGet(() -> getRandomName());

Приведенный выше код не будет вызывать метод getRandomName () .

Помните (из Javadoc), что S поставщик метод, переданный в качестве аргумента, выполняется только тогда, когда необязательный значения нет.

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

4. Измерение Влияния На Производительность

Теперь, чтобы также понять различия в производительности, давайте использовать JMH и посмотрим некоторые фактические цифры:

@Benchmark
@BenchmarkMode(Mode.AverageTime)
public String orElseBenchmark() {
    return Optional.of("baeldung").orElse(getRandomName());
}

И или Еще Get() :

@Benchmark
@BenchmarkMode(Mode.AverageTime)
public String orElseGetBenchmark() {
    return Optional.of("baeldung").orElseGet(() -> getRandomName());
}

При выполнении наших эталонных методов мы получаем:

Benchmark           Mode  Cnt      Score       Error  Units
orElseBenchmark     avgt   20  60934.425 ± 15115.599  ns/op
orElseGetBenchmark  avgt   20      3.798 ±     0.030  ns/op

Как мы видим, влияние на производительность может быть существенным даже для такого простого сценария использования.

Приведенные выше цифры могут немного отличаться, однако orElseGet() явно превзошел или еще() для нашего конкретного примера.

В конце концов, or Else() включает в себя вычисление метода getRandomName() для каждого запуска.

5. Что важно?

Помимо аспектов производительности, другие факторы, заслуживающие внимания, включают в себя:

  • Что делать, если метод выполнит некоторую дополнительную логику? Например, сделает некоторые вставки или обновления БД
  • Даже когда мы назначаем объект параметру or Else() :

    мы все еще создаем “Другой” объект без причины

И именно поэтому для нас важно принять тщательное решение между OrElse() и orElseGet() в зависимости от наших потребностей – по умолчанию имеет смысл использовать orElseGet() каждый раз, если объект по умолчанию уже не построен и доступен напрямую.

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

В этой статье мы изучили нюансы между необязательными методами OrElse() и orElseGet () . Мы также заметили, что иногда такие простые понятия могут иметь более глубокий смысл.

Как всегда, полный исходный код можно найти на Github .