[Java] Stream Optional 개념/예제
Optional은 Java Stream과 함께 도입된 컨셉이며, 어떤 이유로 사용하는지 개념과 예제를 소개합니다.
Stream Optional
Optional은 어떤 객체를 보관하는 컨테이너 클래스이며, null 체크 같은 간단한 기능을 제공합니다.
Optional 객체는 non-null(null이 아닌) 객체이지만, 대신 어떤 값을 갖고 있는데 그 값이 null일 수 있고, 또는 null이 아닐 수 있습니다.
기존엔 객체에 대한 null check 코드를 직접 구현하고 예외처리를 했다면, Optional은 이런 기본적인 기능과 예외처리 기능들을 제공하여 쉽게 다룰 수 있게 합니다.
Optional 객체 생성
non-null 값을 갖고 있는 Optional
아래 예제는 Optional 객체를 생성하고, Optional 안의 데이터를 가져옵니다.
Optional.of(string)
: string 객체를 갖고 있는 Optional 객체를 생성op.get()
: Optional이 갖고 있는 객체 리턴
import java.util.Optional;
public class Example {
public static void main(String[] args) {
String string = "Apple";
Optional<String> op = Optional.of(string);
System.out.println(op.get());
}
}
Output:
Apple
null 값을 갖고 있는 Optional
null을 갖고 있는 Optional 객체를 생성하려면 Optional.ofNullable(obj)
로 null 객체를 전달하면 됩니다.
Optional.get()
으로 객체를 가져오려고 할 때, null이기 때문에 Optional 객체가 NoSuchElementException
에러를 발생시킵니다.
import java.util.NoSuchElementException;
import java.util.Optional;
public class Example {
public static void main(String[] args) {
String string = null;
try {
Optional<String> nullOp = Optional.ofNullable(string);
System.out.println(nullOp.get());
} catch (NoSuchElementException e) {
System.out.println(e);
}
}
}
Output:
java.util.NoSuchElementException: No value present
Optional.isPresent() : non-null 값을 갖고 있는지 확인
Optional.isPresent()
는 Optional이 non-null 객체를 갖고 있을 때 true를 리턴합니다. 우리가 if문으로 객체에 대해서 null 체크를 하는 것과 비슷합니다.
아래와 같은 방식으로 Optional로 null check를 할 수 있으며, null이 아닌 경우 특정 코드를 수행시킬 수 있습니다.
import java.util.Optional;
public class Example {
public static void main(String[] args) {
Optional<String> nullOp = Optional.ofNullable(null);
if (nullOp.isPresent()) {
System.out.println("nullOp.get(): " + nullOp.get());
}
Optional<String> op = Optional.of("Apple");
if (op.isPresent()) {
System.out.println("op.get(): " + op.get());
}
}
}
Output:
op.get(): Apple
Optional.ifPresent() : functional interface
위 코드는 ifPresent()
를 사용하여 좀 더 간단히 구현할 수 있습니다. ifPresent()
는 isPresent()
와 목적이 동일하지만 함수형 인터페이스를 인자로 받는 함수입니다.
Optional이 non-null을 갖고 있을 때 함수에 객체를 전달하며, null을 갖고 있으면 함수를 호출하지 않습니다.
- non-null 객체를 갖고 있는
op
만 함수가 호출됨 - 함수에
string
이 전달되어Optional.get()
을 호출할 필요가 없음
import java.util.Optional;
public class Example {
public static void main(String[] args) {
Optional<String> nullOp = Optional.ofNullable(null);
nullOp.ifPresent(str -> System.out.println("nullOp.get(): " + str));
Optional<String> op = Optional.of("Apple");
op.ifPresent(str -> System.out.println("op.get(): " + str));
}
}
Output:
op.get(): Apple
Optional.orElse() : null 객체에 대한 기본 값
Optional
이 null 객체를 갖고 있을 때, null 대신에 default 값으로 어떤 값을 항상 갖도록 하고 싶을 수 있습니다.
Optional.orElse(a)
는 Optional이 null 값을 갖고 있을 때 a를 리턴합니다.
- 아래 예제를 보면
nullOp
는 null 값을 갖고 있어서"null op"
가 리턴됨 op
는 non-null 값을 갖고 있어서, 그 값이 리턴됨
import java.util.Optional;
public class Example {
public static void main(String[] args) {
Optional<String> nullOp = Optional.ofNullable(null);
System.out.println("nullOp.orElse(): " + nullOp.orElse("null op"));
Optional<String> op = Optional.of("Apple");
System.out.println("op.orElse(): " + op.orElse("non-null op"));
}
}
Output:
nullOp.orElse(): null op
op.orElse(): Apple
Optional.orElseGet() : 함수 결과를 기본값으로
Optional이 null을 갖고 있을 때, 어떤 함수의 결과를 기본 값으로 사용하고 싶을 수도 있습니다.
Optional.orElse()
와 용도는 동일하지만, Optional.orElseGet()
는 아래 예제처럼 함수를 인자로 전달할 수 있습니다.
import java.util.Optional;
public class Example {
public static String getDefaultValue() {
return "ABC";
}
public static void main(String[] args) {
Optional<String> nullOp = Optional.ofNullable(null);
System.out.println("nullOp.orElseGet(): " + nullOp.orElseGet(() -> getDefaultValue()));
Optional<String> op = Optional.of("Apple");
System.out.println("op.orElseGet(): " + op.orElseGet(() -> getDefaultValue()));
}
}
Output:
nullOp.orElseGet(): ABC
op.orElseGet(): Apple
Optional.orElseThrow() : 기본 값 대신에 Exception 발생
Optional.orElseThrow()
는 null 값을 갖고 있을 때, 기본 값을 리턴하는 대신에 Exception 발생시킵니다.
아래 예제를 보시면 쉽게 이해하실 수 있습니다.
import java.util.Optional;
public class Example {
public static void main(String[] args) {
try {
Optional<String> nullOp = Optional.ofNullable(null);
System.out.println("nullOp.orElseGet(): " + nullOp.orElseThrow(NullPointerException::new));
} catch (NullPointerException e) {
System.out.println(e);
}
try {
Optional<String> op = Optional.of("Apple");
System.out.println("op.orElseGet(): " + op.orElseThrow(NullPointerException::new));
} catch (NullPointerException e) {
System.out.println(e);
}
}
}
Output:
java.lang.NullPointerException
op.orElseGet(): Apple