긴말은 생략하고 NullPointerException 발생할 가능성이 있는객체를 한번더 wrapping 해서 방어하는 로직을 짤때 사용
if(member != null){
someLogic...
}
if(... != null){
someLogic...
}
보기만해도 짜증나니 바로 본론으로 들어가자.
Optional<String> opt = Optional.of("value");
null 이 아닌값을 Optional 지네릭 타입에 해당하는 값을 할당할 수 있는 메소드
Optional<String> opt = Optional.ofNullable("value");
null 이 가능한 값으로 Optional 을 생성하며 값이 있을경우 해당 지네릭 타입으로 초기화 하지만 null 이 들어갈 경우 빈 Optional 로 객체를 초기화함
public static <T> Optional<T> ofNullable(T value)
{return value == null ? empty() : of(value);}
Optional<String> opt = Optional.of("value");
String value = opt.get();
Optional 에 할당된 값을 가져오고 싶을경우 get() 메소드를 사용하여 가져 올 수 있다.
하지만 Optional 에 대한 값이 비어있을 경우에 .get() 메소드 사용시 NoSuchElementException 이 발생할 수 있으니 주의해서 사용하자!
Optional<String> opt = Optional.of("value");
opt.isPresent(); // true
opt.isEmpty(); // false
Optional 에 값이 있는경우 isPresent -> true 없을경우 isEmpty -> false 를 반환한다.
// Lamda 식을 사용하지 않고 Optional 을 사용할 경우
/*
람다식 미사용
*/
Member member = new Member(...);
Optional<Member> optM = Optional.of(member);
if(optM.isPresent){
someLogic...;
}
if(optM.isEmpty){
someLogic...;
}
/*
람다식 if 문 처럼 사용하는방법
값이 null 이거나 빈값일 경우 해당 로직은 실행되지 않는다.
*/
optM.ifPresent(value -> someLogic...);
optM.ifPresentOrElse(
//value -> null 이거나 빈값이 아닐경우
value -> someLogic...,
//value -> null 이거나 빈값일 경우
() -> someLogic...
)
// orElse
Optional<String> opt = Optional.empty();
String value = opt.orElse("초기값");
System.out.println(value) -> 결과: 초기값
-------
Optional<String> opt = Optional.ofNullable("당근당근");
String value = opt.orElse("토마토");
System.out.println(value) -> 결과: 당근당근
orElse -> 값이 비어있을경우 orElse 메소드로 넣은 파라미터 인자값이 반환된다. 하지만 값이 있을경우 기존 값을 반환함
// orElseGet
Optional<String> opt = Optional.empty();
String value = opt.orElseGet(() -> someLogic to return Type);
System.out.println(value) -> 결과: 초기값
-------
Optional<String> opt = Optional.ofNullable("당근당근");
String value = opt.orElseGet(() -> "토마토");
System.out.println(value) -> 결과: 당근당근
orElseGet 은 orElse 와 거의 유사하나 Supplier @FuntionalInterface 를 파라미터로 받아 내부 람다식으로 코드를 구성할 수 있다.
// or 는 같은 값이나 return 값이 Optional 이어야함.
// 값이 없을때 Optional을 리턴해야함.
Optional<String> opt = Optional.empty();
Optional<String> result = opt.or(()-> Optional.of("default"));
값이 없을경우 다른 Optional 을 리턴하는 메소드는 or()
Optional<String> opt = Optional.empty();
opt.orElseThorw(()-> new NullpointerException());
값이 없을경우 익셉션을 발생시킴.
Optional<String> opt = Optional.ofNullable("123456");
Optional<Integer> opt1 = opt.map(Integer::parseInt);
Optional<Anonymous> test = Optional.of(new Anonymous(Optional.of("anonymous")));
System.out.println(test.map(Anonymous::getEname)); // Optional[Optional[anonymous]]
System.out.println(test.flatMap(Anonymous::getEname)); // Optional[anonymous]
static class Anonymous{
private Optional<String> name;
public Anonymous(Optional<String> name){
this.name = name;
}
}
map -> 다른 Optional 을 새로운 타입으로 변환할때 사용함.
만약 opt 가 비어있을경우에는 map 이 실행되지 않고 빈객체가 반환된다.
flatMap -> Optional 이 2중 중첩으로 되어있을경우 그 내부에 있는 Optional 을 리턴함.
Optional<String> strOpt = Optional.ofNullable("abcdefg");
Optional<String> afterFiltered = strOpt.filter(str -> str.length()>3);
afterFiltered.ifPresent(System.out::println);
filter 참인 값에 대해 Optional 로 리턴함
만약 부합하는 객체가 없을경우 empty 값을 리턴함
개인적으로 Optional 을 가장 많이 사용하는 메소드들을 정리해보았고 또 다른 방법으로 이용한다면 그때그때 정리 해보자.