[Java] Java 8 에서 자주 만나는 것들 3

Java 8 에서 자주 만나는 것들 마지막 Optional이다.

Optional

Optional<T>NullPointerException을 회피하기 위한 래퍼 클래스(Wrapper class)이다.

Optional 생성

바로 간단한 예제부터 살펴보자.

1
2
3
4
private static void optionalPractice1() {
  Optional<String> opt = Optional.ofNullable("Hello Optional");
  System.out.println(opt.get());
}
1
Hello Optional

of() 또는 ofNullable() 메서드로 Optional 객체를 생성할 수 있다. of()null인 값을 인자로 받을 수 없다. 따라서 null일 가능성이 있는 것은 ofNullable() 메서드를 사용한다.

Optional 접근

위 예제에서 자연스럽게 사용하고 있는데, Optional 객체에 저장된 값을 가져오기 위해 get()을 사용한다. 저장된 값이 null일 수도 있으므로 isPresent() 메서드를 써서 null인지 아닌지를 확인한다.

1
2
3
4
5
private static void optionalPractice2() {
  Optional<String> opt = Optional.ofNullable("Hello Optional");
  if (opt.isPresent())
    System.out.println(opt.get());
}

만약 Optional 객체에 저장된 값이 null일 때를 처리하는 메서드가 있다.

  1. orElse() : 저장된 값이 존재하면 그 값을 반환하고, 값이 존재하지 않으면 인수로 전달된 을 반환한다.
  2. orElseGet() : 저장된 값이 존재하면 그 값을 반환하고, 값이 존재하지 않으면 인수로 전달된 람다 표현식의 결과를 반환한다.
  3. orElseThrow() : 저장된 값이 존재하면 그 값을 반환하고, 값이 존재하지 않으면 인수로 전달된 예외를 발생시킨다.
1
2
3
4
5
6
7
private static void optionalPractice3() {
  Optional<String> opt = Optional.empty();

  System.out.println(opt.orElse("Optional이 비어있으면 반환되는 값"));
  System.out.println(opt.orElseGet(() -> "Optional이 비어있으면 반환되는 값"));
  opt.orElseThrow(() -> new RuntimeException("Optional이 비어있습니다."));
}
1
2
3
4
5
6
7
Optional이 비어있으면 반환되는 값
Optional이 비어있으면 반환되는 값
Exception in thread "main" java.lang.RuntimeException: Optional이 비어있습니다.
	at com.minhojang.practice.OptionalPractice.lambda$optionalPractice3$1(OptionalPractice.java:37)
	at java.util.Optional.orElseThrow(Optional.java:290)
	at com.minhojang.practice.OptionalPractice.optionalPractice3(OptionalPractice.java:37)
	at com.minhojang.practice.OptionalPractice.main(OptionalPractice.java:11)

위 예시를 보고 orElse()orElseGet()이 똑같다고 생각할 수 있다. 이 둘의 차이는 인자로 받은 것을 항상 실행하냐 안 하냐이다. 아래 예시를 보면 더 명확한데, optnull 여부에 관계없이 4번 라인의 someLogic()은 항상 실행된다. 5번 라인의 someLogic()optnull인 경우에만 실행된다.

1
2
3
4
5
6
7
8
9
10
private static void optionalPractice3() {
  Optional<String> opt = Optional.empty();

  System.out.println(opt.orElse(someLogic()));
  System.out.println(opt.orElseGet(() -> someLogic()));
}

private static String someLogic() {
  return "로직을 실행한 결과";
}
1
2
로직을 실행한 결과
로직을 실행한 결과

기본 타입의 Optional 클래스

Stream에서도 IntStream, LongStream, DoubleStream이 있듯이 Optional에도 OptionalInt, OptionalLong, OptionalDouble이 있다.

아래 예제에서 findFirst() 메서드가 OptionalInt 형을 반환하고 있다. 그에 따라 해당 결과값이 존재한다면 출력하는 코드이다.

1
2
3
4
5
private static void optionalPractice4() {
  IntStream stream = IntStream.of(4, 2, 1, 3);
  OptionalInt result = stream.findFirst();
  result.ifPresent(System.out::println);
}
1
4

댓글 남기기