Optional 사용예제

Patrick YOO·2022년 1월 2일
0

Optional 이란

긴말은 생략하고 NullPointerException 발생할 가능성이 있는객체를 한번더 wrapping 해서 방어하는 로직을 짤때 사용

if(member != null){
    someLogic...
}
if(... != null){
    someLogic...
}

보기만해도 짜증나니 바로 본론으로 들어가자.

Optional 생성방법

Optional<String> opt = Optional.of("value");

null 이 아닌값을 Optional 지네릭 타입에 해당하는 값을 할당할 수 있는 메소드

  • of(null) 이 들어갈 경우 NullpointerException 발생
Optional<String> opt = Optional.ofNullable("value");

null 이 가능한 값으로 Optional 을 생성하며 값이 있을경우 해당 지네릭 타입으로 초기화 하지만 null 이 들어갈 경우 빈 Optional 로 객체를 초기화함

  • Optional.empty(), 와 Optional.ofNullable(null) 은 같다.
public static <T> Optional<T> ofNullable(T value) 
{return value == null ? empty() : of(value);}

Optional 값 가져오기

Optional<String> opt = Optional.of("value");

String value = opt.get();

Optional 에 할당된 값을 가져오고 싶을경우 get() 메소드를 사용하여 가져 올 수 있다.
하지만 Optional 에 대한 값이 비어있을 경우에 .get() 메소드 사용시 NoSuchElementException 이 발생할 수 있으니 주의해서 사용하자!

Optional 빈값 체크

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, orElseGet, or 사용방법

// 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()

orElseThow

Optional<String> opt = Optional.empty();
opt.orElseThorw(()-> new NullpointerException());

값이 없을경우 익셉션을 발생시킴.

map , flatMap

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 을 리턴함.

filter

Optional<String> strOpt = Optional.ofNullable("abcdefg");

Optional<String> afterFiltered = strOpt.filter(str -> str.length()>3);
afterFiltered.ifPresent(System.out::println);

filter 참인 값에 대해 Optional 로 리턴함
만약 부합하는 객체가 없을경우 empty 값을 리턴함

총총

개인적으로 Optional 을 가장 많이 사용하는 메소드들을 정리해보았고 또 다른 방법으로 이용한다면 그때그때 정리 해보자.

profile
자유인을 꿈꾸는 개발자

0개의 댓글