자바 Optional 클래스

savannah030·2022년 2월 28일
0

JAVA

목록 보기
1/1

똑똑한 Intellij는...

내가 이렇게 적었던 코드를

// 엔티티 객체 없으면(글을 새로 쓰는 경우) 필드 값을 초기화하지않은 dto 생성 
if (!entity.isPresent()){
    return new MyBoardResponseDto();
}
// 엔티티 객체 있으면 그 객체의 필드로 dto 초기화
else{
    return new MyBoardResponseDto(entity.get());
}

이렇게 바꿔주었다.

entity.map(MyBoardResponseDto::new).orElseGet(MyBoardResponseDto::new);

이렇게 적었던 코드를2

if(entity.isPresent()){
	entity.get().increaseHits()
}

이렇게 바꿔주었다.2

entity.ifPresent(Board::increaseHits);

orElse와 orElseGet의 차이

근데 문득 궁금증이 생겼다. 위의 예 1에서 orElseGet()을 orElse()로 쓰면 안될까?

둘의 차이는 orElseGet이 orElse의 게으른 버전이라는 것 정도만 자바 인 액션에서 어렴풋이 봤던 것 같다.
그래서 orElse로 바꿨더니 이런 에러가 뜬다.

dto가 함수형 인터페이스가 아니라는데, 그게 무슨 말이지?

이 코드에서 entity는 Board 엔티티이고 MyBoardResponseDto는 Board엔티티에서 변환한 DTO다. 즉, 둘이 다른 형이다.

그리고 orElse와 orElseGet의 차이를 찾아보았다

orElse는
- null이든 아니든 항상 호출된다.
- T 타입의 other를 그대로 반환한다.

orElseGet은 T 타입의 other
- null일때만 호출된다.
- T 타입의 other를 Supplier를 통해 반환한다.
** 여기서 Supplier other의 값을 반환하는 함수형 인터페이스 정도로 생각하면 될듯

그래서 내 생각에 orElse가 안되는 이유는,
orElse는 other형을 그대로 반환하기 때문에 value와 other의 형이 같아야 하는데, 내 경우에는 value로 Board 엔티티를, other로 MyBoardResponseDto를 써야 했으므로, orElse가 아닌 orElseGet만 쓸 수 있었던 것 같다.

orElseGet은 Supplier라는 함수형 인터페이스 덕분에 value와 other형이 굳이 같지 않아도 되기 때문에 쓸 수 있었던 거고.

느낀점

책으로만 볼 때는 orElseGet이 orElse의 게으른 버전이라는 되게 추상적인 설명이었어서 별로 와닿지 않았는데, 이렇게 직접 실전에서 부딪히니 차이를 정리할 수 있었고, 기억에 더 오래 남을 것 같다.

profile
백견이불여일타

0개의 댓글