Функционально переписывая присвоение из Optional без выполнения логики "else" - PullRequest
0 голосов
/ 28 августа 2018

В моем коде есть следующее:

Optional<Foo> optionalFoo = fooDAO.findByName(name);
Foo foo;
if(!optionalFoo.isPresent()) {
    foo = fooDAO.addFoo(name);
} else {
    foo = optionalFoo.get();
}

IntelliJ выскочил подсказку с надписью can be replaced with single expression in functional style. Я попытался заменить этот блок на:

Optional<Foo> optionalFoo = fooDAO.findByName(name);
Foo foo = optionalFoo.orElse(fooDAO.addFoo(name));

Это привело к сбою тестов, так как fooDAO.addFoo(name) вызывается независимо от того, пуст Optional или нет, и логика в addFoo не должна выполняться, если Foo уже существует.

Можно ли функционально переписать оригинальный блок, не вызывая fooDAO.addFoo(name), если в этом нет необходимости?

Ответы [ 3 ]

0 голосов
/ 28 августа 2018

orElse принимает значение в качестве аргумента, поэтому переданная вами функция всегда выполняется.

Для создания foo при необходимости вы должны использовать orElseGet:

Foo foo = fooDAO.findByName(name).orElseGet(() -> fooDAO.addFoo(name));
0 голосов
/ 28 августа 2018

Используйте Optional.orElseGet с лямбда-выражением:

Optional<Foo> optionalFoo = fooDAO.findByName(name);
Foo foo = optionalFoo.orElseGet(()->fooDAO.addFoo(name));
0 голосов
/ 28 августа 2018

Вы ищете orElseGet, который принимает Supplier, который вызывается только при отсутствии значения:

Foo foo = fooDAO.findByName(name)
    .orElseGet(() -> fooDAO.addFoo(name));

Я думаю, что name должен быть эффективно окончательным, чтобы это работало.

...