Скажем, я использую дополнительные функции, и у меня есть:
A a;
....
Optional.ofNullable(a)
.map(A::getB)
.map(B::getC)
.ifPresent(c -> ...) // do something with c
Однако, если по какой-либо причине я хочу войти, когда B :: getC равен нулю (или когда a равен нулю). Есть ли какая-то идиома для борьбы с этим? Я мог бы сделать несколько вложенных вызовов ifPresent, но это очень многословно.
Лучшее, что я мог придумать, это класс FunctionalHelper, который оборачивает некоторые дополнительные методы и добавляет другие для поддержки ведения журнала (log4j):
private static final Logger LOG = //...
private static final FunctionalHelper FH
= new FunctionalHelper(LOG, Level.DEBUG);
FH.ofNullable(a, Level.WARN, "You gave me a null A"))
.map(FH.logNull(A::getB, "b was null for a: {}", a-> FH.args(a.getName()))
.map(B::getC)
.ifPresent(c -> ...) // do something with c
Это работает, но немного похоже на решение проблемы. Есть ли какая-то идиома (или, по крайней мере, стандартная библиотека) для работы с такими вещами?
(Мне также интересно, как правильно обращаться с проверенными исключениями, возникающими в цепочке, но, возможно, это отдельный вопрос.)
ОБНОВЛЕНИЕ: В ответ на @Ole V.V., вот пример с Optionals (ОБНОВЛЕНИЕ2: я немного подправил его, чтобы соответствовать семантике поставщика log4j varags, но с функциями:
private static final FunctionalHelper FH = new FunctionalHelper(LOG, Level.DEBUG);
void foo(A someA) {
FH.ofNullable(someA, Level.WARN, "You gave me a null A")
.map(FH.logNull(A::getB, "B was null for A: {}", A::getName))
.map(FH.logNull(B::getC, "C was null for B: {}", B::getName))
.ifPresent(c -> { /* do something with c */});
}
Вот реализация If-else:
void foo2(A a) {
if (a == null) LOG.debug("You gave me a null A");
else {
B b = a.getB();
if (b == null) LOG.debug("B was null for a: {}", a::getName);
else {
String c = b.getC();
if (c == null) LOG.debug("C was null for a: {}", b::getName);
else { /* do something with c */ }
}
}
}
Я бы сказал, что первое легче читать. Также проще изменить существующую цепочку Optional, чтобы добавить что-то, когда это необходимо.