- null 체크를 위해 if문을 사용하는 적이 많았다. Optional을 만나기 전까지는..
- Optional은 Java 8 부터 추가되었다.
- nullable인 값을 감싸는 wrapper 클래스다. 이 Optinoal을 이용해서 null 체크를 하여 NPE 발생을 줄일 수 있다.
Optional 객체 생성
- of()와 ofNullable()을 사용해 객체를 생성한다.
1. of()
String str = "java";
Optional<String> opt1 = Optional.of(str);
Optional<String> opt2 = Optional.of("java");
2. ofNullable()
- 만약 참조변수 값이 null일 가능성이 있다면 ofNullable()을 사용해야한다. of()를 사용할 때 참조변수 값이 Null이면 NPE이 발생하기 때문이다.
Optional<String> opt1 = Optional.of(null); // NPE 발생
Optional<String> opt2 = Optional.ofNullable(null); // Optional.empty
Optional 타입 참조변수 기본값 초기화
- null과 empy()로 초기화하는 방법이 있다.
// 1. null 초기화
Optional<String> opt1 = null;
// 2. empty() 초기화
Optional<String> opt2 = Optional.<String>empty();
Optional 객체 값 가져오기
get(), orElse()
- get()을 사용하여 가져 온다. 값이 null일 경우 NoSuchElementException이 발상한다. 이때 orElse()를 사용하여 대체할 값을 지정한다.
Optional<String> opt1 = Optional.of("java")
String str1 = opt1.get();
String str2 = opt1.orElse("kotlin"); // null 이면 kotlin 반환
orElseGet(), orElseThrow()
- orElseGet()은 null을 대체할 값을 반환하는 람다식을 지정할 수 있다.
- orElseThrow()는 null일 때 Exception을 지정하여 발생시킬 수 있다.
String str1 = opt1.orElseGet(() -> "kotlin");
String str2 = opt1.orElseThrow(NullPointerException::new);
isPresent(), ifPresent(), ifPresentOrElse()
- isPresent()는 Optional의 값이 null이면 false, 아니면 true를 반환한다.
- ifPresent()는 값이 null이 아닐 때 실행되는 람다식을 지정할 수 있다.
- ifPresentOrElse()는 if else문처럼 null이면 else문, 아니면 if문을 통과하는 것처럼 실행한다.
String str = "java";
if(str != null) {
System.out.println("str = " + str);
}
// isPresent()
if(Optional.ofNullable(str).isPresent()) {
System.out.println("str = " + str);
}
// ifPresent()
Optional.ofNullable(str).ifPresent(System.out::println);
// ifPresentOrElse()
Optional.ofNullable(str).ifPresentOrElse(
v -> System.out.println(v), // null이 아니면 실행
() -> System.out.println("str = null") // null이면 실행
);
// str = java
// str = java
// java
메서드
map( () → {} )
- map()은 정의한 람다를 실행한 뒤 결과값을 Optional 객체로 리턴한다. 만약 값이 없으면 empty인 Optinoal을 리턴한다.
String str = "java";
Optional<String> opt1 = Optional.ofNullable(str);
Optional<String> opt2 = opt1.map(ss -> ss + " & kotlin");
Optional<String> opt3 = opt2.map(ss -> ss + " & spring");
System.out.println(opt3.get());
// java & kotlin & spring
flatMap()
- map()과 같은 실행을 하지만 map()은 결과값을 Optional로 감싸서 리턴되지만, flatMap()은 Optional 객체를 리턴하게 되면 리턴 타입 자체가 Optional이 된다.
- 만약 map()에서 Optional타입이 결과값이 되면 그것을 또 Optional로 감싸져서 리턴된다.
String str = "java";
Optional<String> opt1 = Optional.ofNullable(str);
// map()을 사용하여 Optional 객체를 리턴할 경우
Optional<Optional<String>> opt2 = opt1.map(s -> Optional.ofNullable(s));
// flatMap()을 사용하여 Optional 객체를 리턴할 경우
Optional<String> optional = opt1.flatMap(s -> Optional.ofNullable(s));
System.out.println(opt2.get());
System.out.println(opt1.get());
// Optional[java]
// java
filter( () → 조건 )
- filter()는 정의한 조건이 맞으면 값을 그대로 리턴한다. 만약 조건이 맞지 않으면 empty인 Optional을 리턴한다.
String str = "java";
Optional<String> opt1 = Optional.ofNullable(str);
Optional<String> opt2 = opt1.filter(s -> s.length() < 3);
System.out.println(opt2.isEmpty());
// true
사용시 주의사항에 대한 글
참고
댓글