[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
일 때를 처리하는 메서드가 있다.
orElse()
: 저장된 값이 존재하면 그 값을 반환하고, 값이 존재하지 않으면 인수로 전달된 값을 반환한다.orElseGet()
: 저장된 값이 존재하면 그 값을 반환하고, 값이 존재하지 않으면 인수로 전달된 람다 표현식의 결과를 반환한다.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()
이 똑같다고 생각할 수 있다.
이 둘의 차이는 인자로 받은 것을 항상 실행하냐 안 하냐이다.
아래 예시를 보면 더 명확한데, opt
의 null
여부에 관계없이 4번 라인의 someLogic()
은 항상 실행된다.
5번 라인의 someLogic()
은 opt
가 null
인 경우에만 실행된다.
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
댓글 남기기