Java 8 ifPresent()
에서 Optional
API 의 방법 을 이해하려고합니다 .
나는 간단한 논리가 있습니다.
Optional<User> user=...
user.ifPresent(doSomethingWithUser(user.get()));
그러나 이로 인해 컴파일 오류가 발생합니다.
ifPresent(java.util.functionError:(186, 74) java: 'void' type not allowed here)
물론 다음과 같이 할 수 있습니다.
if(user.isPresent())
{
doSomethingWithUser(user.get());
}
그러나 이것은 정확히 어수선한 null
수표 와 같습니다 .
코드를 다음과 같이 변경하면 :
user.ifPresent(new Consumer<User>() {
@Override public void accept(User user) {
doSomethingWithUser(user.get());
}
});
코드가 더러워 져서 예전 null
수표 로 돌아 가야한다고 생각하게합니다 .
어떤 아이디어?
답변
Optional<User>.ifPresent()
Consumer<? super User>
인수로 취합니다 . 유형이 void 인 표현식을 전달합니다. 그래서 그것은 컴파일되지 않습니다.
소비자는 람다 식으로 구현됩니다.
Optional<User> user = ...
user.ifPresent(theUser -> doSomethingWithUser(theUser));
또는 메서드 참조를 사용하면 더 간단합니다.
Optional<User> user = ...
user.ifPresent(this::doSomethingWithUser);
이것은 기본적으로
Optional<User> user = ...
user.ifPresent(new Consumer<User>() {
@Override
public void accept(User theUser) {
doSomethingWithUser(theUser);
}
});
아이디어는 doSomethingWithUser()
사용자가있는 경우에만 메서드 호출이 실행된다는 것입니다. 코드는 메서드 호출을 직접 실행하고 void 결과를에 전달하려고합니다 ifPresent()
.
답변
@JBNizet의 답변 외에도 일반적인 사용 사례 ifPresent
는 다음 .isPresent()
과 .get()
같이 결합하는 것입니다 .
이전 방식 :
Optional opt = getIntOptional();
if(opt.isPresent()) {
Integer value = opt.get();
// do something with value
}
새로운 방식:
Optional opt = getIntOptional();
opt.ifPresent(value -> {
// do something with value
})
이것은 나에게 더 직관적입니다.
답변
간단하게 만들 수 있는데 왜 복잡한 코드를 작성합니까?
실제로 Optional
클래스 를 절대적으로 사용하려는 경우 가장 간단한 코드는 이미 작성한 코드입니다.
if (user.isPresent())
{
doSomethingWithUser(user.get());
}
이 코드는
- 읽을 수있는
- 디버그하기 쉬움 (중단 점)
- 까다 롭지 않다
Oracle이 Optional
Java 8에 클래스를 추가 했다고해서이 클래스가 모든 상황에서 사용되어야한다는 의미는 아닙니다.
답변
flatMap을 사용하십시오. 값이 있으면 flatMap은 해당 값만 포함하는 순차 Stream을 반환하고, 그렇지 않으면 빈 Stream을 반환합니다. 따라서 사용할 필요가 없습니다 ifPresent()
. 예:
list.stream().map(data -> data.getSomeValue).map(this::getOptinalValue).flatMap(Optional::stream).collect(Collectors.toList());
답변
다음과 같은 메서드 참조를 사용할 수 있습니다.
user.ifPresent(ClassNameWhereMethodIs::doSomethingWithUser);
메소드 ifPresent()
get Consumer
object as a paremeter and (from JavaDoc ) : “값이있는 경우 값으로 지정된 소비자를 호출합니다.” 가치는 귀하의 변수 user
입니다.
또는이 메서드 doSomethingWithUser
가 User
클래스에 있고 그렇지 않은 경우 다음 static
과 같은 메서드 참조를 사용할 수 있습니다.
user.ifPresent(this::doSomethingWithUser);