java8을 사용하여 다음 코드를 바꾸고 싶습니다 Optional
.
public Obj getObjectFromDB() {
Obj obj = dao.find();
if (obj != null) {
obj.setAvailable(true);
} else {
logger.fatal("Object not available");
}
return obj;
}
다음 의사 코드는 orElseRun
방법 이 없기 때문에 작동하지 않지만 어쨌든 내 목적을 보여줍니다.
public Optional<Obj> getObjectFromDB() {
Optional<Obj> obj = dao.find();
return obj.ifPresent(obj.setAvailable(true)).orElseRun(logger.fatal("Object not available"));
}
답변
Java 9 이상을 사용하면 다음과 같이 ifPresentOrElse
할 수 있습니다.
Optional<> opt = dao.find();
opt.ifPresentOrElse(obj -> obj.setAvailable(true),
() -> logger.error("…"));
vavr 등을 사용하여 커링 하면 더 깔끔한 코드를 얻을 수 있지만 아직 시도하지 않았습니다.
답변
나는 당신이 하나의 진술로 그것을 할 수 있다고 생각하지 않습니다. 더 나은 방법 :
if (!obj.isPresent()) {
logger.fatal(...);
} else {
obj.get().setAvailable(true);
}
return obj;
답변
Java 8 Spring은 ifPresentOrElse
“옵션과 함께 작동하는 유틸리티 메소드”에서 제공 하여 원하는 것을 달성합니다. 예는 다음과 같습니다.
import static org.springframework.data.util.Optionals.ifPresentOrElse;
ifPresentOrElse(dao.find(), obj -> obj.setAvailable(true), () -> logger.fatal("Object not available"));
답변
이것을 여러 문장으로 분할해야합니다. 이를 수행하는 한 가지 방법은 다음과 같습니다.
if (!obj.isPresent()) {
logger.fatal("Object not available");
}
obj.ifPresent(o -> o.setAvailable(true));
return obj;
또 다른 방법 (과도하게 설계되었을 수 있음)은 다음을 사용하는 것입니다 map
.
if (!obj.isPresent()) {
logger.fatal("Object not available");
}
return obj.map(o -> {o.setAvailable(true); return o;});
만약 obj.setAvailable
편리하게 반환 obj
, 다음 수 단순히 두 번째 예 :
if (!obj.isPresent()) {
logger.fatal("Object not available");
}
return obj.map(o -> o.setAvailable(true));
답변
우선, dao.find()
를 반환 Optional<Obj>
하거나 생성해야합니다.
예 :
Optional<Obj> = dao.find();
또는 다음과 같이 스스로 할 수 있습니다.
Optional<Obj> = Optional.ofNullable(dao.find());
이것은 Optional<Obj>
존재하거나 Optional.empty()
존재하지 않으면 반환 됩니다 .
이제 해결책을 찾아 보겠습니다.
public Obj getObjectFromDB() {
return Optional.ofNullable(dao.find()).flatMap(ob -> {
ob.setAvailable(true);
return Optional.of(ob);
}).orElseGet(() -> {
logger.fatal("Object not available");
return null;
});
}
이것은 당신이 찾고있는 하나의 라이너입니다 🙂
답변
가 이다.orElseRun
방법은 있지만라고합니다 .orElseGet
.
의사 코드의 주요 문제 .isPresent
는 Optional<>
. 그러나 메서드 .map
가있는 Optional<>
을 반환합니다 orElseRun
.
한 문장에서 정말로 이것을하고 싶다면 이것은 가능하다 :
public Optional<Obj> getObjectFromDB() {
return dao.find()
.map( obj -> {
obj.setAvailable(true);
return Optional.of(obj);
})
.orElseGet( () -> {
logger.fatal("Object not available");
return Optional.empty();
});
}
그러나 이것은 이전에 가졌던 것보다 훨씬 어색합니다.
답변
예를 들어 다음과 같은 몇 가지 “한 줄”솔루션을 만들 수있었습니다.
obj.map(o -> (Runnable) () -> o.setAvailable(true))
.orElse(() -> logger.fatal("Object not available"))
.run();
또는
obj.map(o -> (Consumer<Object>) c -> o.setAvailable(true))
.orElse(o -> logger.fatal("Object not available"))
.accept(null);
또는
obj.map(o -> (Supplier<Object>) () -> {
o.setAvailable(true);
return null;
}).orElse(() () -> {
logger.fatal("Object not available")
return null;
}).get();
처럼, 뭔가를 아주 좋은 보이지 않는 orElseRun
더 나은 것,하지만 난 당신이 정말 한 줄 솔루션을 원하는 경우의 Runnable에 해당 옵션이 허용 생각합니다.