Optional 만드는 법
• of – Null이 아닌 오브젝트를 이용해 Optional을 만들 때
• empty – 빈 Optional을 만들 때
• ofNullable – Null인지 아닌지 알지 못하는 오브젝트로 Optional을 만들 때
private static final Optional<?> EMPTY = new Optional<>(null);
public static <T> Optional<T> of(T value) {
return new Optional<>(Objects.requireNonNull(value));
}
public static<T> Optional<T> empty() {
Optional<T> t = (Optional<T>) EMPTY;
return t;
}
public static <T> Optional<T> ofNullable(T value) {
return value == null ? (Optional<T>) EMPTY
: new Optional<>(value);
}
Optional 안에 있는 값을 확인하고 꺼내는 법
• isPresent – 안의 오브젝트가 null인지 아닌지 체크. Null이 아닐 시 true
• get – Optional 안의 값을 추출. Null이라면 에러
• orElse – Optional이 null이 아니라면 Optional 안의 값을, null이라면 other로 공급된 값을 리턴
• orElseGet – Optional이 null이 아니라면 Optional 안의 값을, null이라면 supplier로 공급되는 값을 리턴
• orElseThrow – Optional이 null이 아니라면 Optional 안의 값을, null이라면 exceptionSupplier로 공급되는 exception
public boolean isPresent() {
return value != null;
}
public T get() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
public T orElse(T other) {
return value != null ? value : other;
}
public T orElseGet(Supplier<? extends T> supplier) {
return value != null ? value : supplier.get();
}
public T orElseThrow() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
public T orElseThrow() {
if (value == null) {
throw new NoSuchElementException("No value present");
}
return value;
}
public <X extends Throwable> T orElseThrow(Supplier<? extends X> exceptionSupplier) throws X {
if (value != null) {
return value;
} else {
throw exceptionSupplier.get();
}
}
사용예
Optional<String> maybeEmail = Optional.of(someEmail);
Optional<String> maybeEmail2 = Optional.empty();
Optional<String> maybeEmail3 = Optional.ofNullable(someEmail);
Optional<String> maybeEmail4 = Optional.ofNullable(nullEmail);
String email = maybeEmail.get();
if (maybeEmail2.isPresent()) {
System.out.println(maybeEmail2.get());
}
String defaultEmail = "default@email.com";
String email3 = maybeEmail2.orElse(defaultEmail);
String email4 = maybeEmail2.orElseGet(() -> defaultEmail);
String email5 = maybeEmail2.orElseThrow(() -> new RuntimeException("email not present"));
Optional 응용을 위해 알아야 할 것들
• ifPresent – Optional이 null이 아니라면 action을 실행
• map – Optional이 null이 아니라면 mapper를 적용
• flatMap – mapper의 리턴 값이 또 다른 Optional이라면 한 단계의 Optional이 되도록 납작하게 해줌
Optional<Optional<T>> --> Optional<T>
public void ifPresent(Consumer<? super T> action) {
if (value != null) {
action.accept(value);
}
}
public <U> Optional<U> map(Function<? super T, ? extends U> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent()) {
return empty();
} else {
return Optional.ofNullable(mapper.apply(value));
}
}
public <U> Optional<U> flatMap(Function<? super T, ? extends Optional<? extends U>> mapper) {
Objects.requireNonNull(mapper);
if (!isPresent()) {
return empty();
} else {
@SuppressWarnings("unchecked")
Optional<U> r = (Optional<U>) mapper.apply(value);
return Objects.requireNonNull(r);
}
}
사용예
public static void main(String[] args) {
Optional<User> maybeUser = Optional.ofNullable(maybeGetUser(true));
maybeUser.ifPresent(System.out::println);
Optional<Integer> maybeId = Optional.ofNullable(maybeGetUser(true))
.map(user -> user.getId());
maybeId.ifPresent(System.out::println);
String userName = Optional.ofNullable(maybeGetUser(true))
.map(User::getName)
.map(name -> "The name is " + name)
.orElse("Name is empty");
System.out.println(userName);
Optional<String> maybeEmail = Optional.ofNullable(maybeGetUser(true))
.flatMap(User::getEmailAddress);
maybeEmail.ifPresent(System.out::println);
}
반응형