[ JAVA ] Optional
Optional μ΄λ?
κ°λ°μ ν λ κ°μ₯ λ§μ΄ λ°μνλ μμΈ μ€ νλλ λ°λ‘ NullPointerException μ λλ€. NullPointerException μ νΌνκ³ null 체ν¬νλ λ‘μ§μ μ€μ΄κΈ° μν΄ λΉ κ°μΌ λ null λμ μ΄κΈ°κ°μ μ¬μ©νκΈΈ κΆμ₯νκ³€ ν©λλ€.
List<String> names = getNames();
names.sort(); // names κ° null μ΄λΌλ©΄ NullPointerException μ΄ μΌμ΄λλ€.
μλ° 8μμλ Optional<T> ν΄λμ€λ₯Ό μ΄μ©ν΄μ NullPointerException μ λ°©μ§ν μ μμ΅λλ€.
μ¦, 볡μ‘ν 쑰건문 μμ΄λ λ(null) κ°μΌλ‘ μΈν΄ λ°μνλ μμΈλ₯Ό μ²λ¦¬ν μ μκ² λ©λλ€.
public final class Optional<T> {
// If non-null, the value; if null, indicates no value is present
private final T value;
...
}
value μ κ°μ μ μ₯νκΈ° λλ¬Έμ κ°μ΄ null μ΄λλΌλ λ°λ‘ μ°Έμ‘° μ NullPointerException κ° λμ§ μκ³ , ν΄λμ€μ΄κΈ° λλ¬Έμ κ°μ’ λ©μλλ₯Ό μ 곡ν΄μ€λλ€.
Optional<T> ν΄λμ€
Integerλ Double ν΄λμ€μ²λΌ 'T'νμ μ κ°μ²΄λ₯Ό ν¬μ₯ν΄ μ£Όλ λνΌ ν΄λμ€(Wrapper class)μ λλ€. λ°λΌμ Optional μΈμ€ν΄μ€λ λͺ¨λ νμ μ μ°Έμ‘° λ³μλ₯Ό μ μ₯ν μ μμ΅λλ€.
Optional κ°μ²΄μ μμ±
1. Optional.empty() λΉ κ°μ²΄ μμ±
Optional<String> optional = Optional.empty();
System.out.println(optional); // Optional.empty
System.out.println(optional.isPresent()); // false
2. of() , ofNullable()
• of() λ©μλ : nullμ΄ μλ λͺ μλ κ°μ κ°μ§λ Optional κ°μ²΄λ₯Ό λ°νν©λλ€.
• of() λ©μλλ₯Ό ν΅ν΄ μμ±λ Optional κ°μ²΄μ nullμ΄ μ μ₯λλ©΄ NullPointerException μμΈκ° λ°μ
// Optionalμ valueλ μ λ nullμ΄ μλλ€.
Optional<String> optional = Optional.of("MyName");
• ofNullable() λ©μλ : μ°Έμ‘° λ³μμ κ°μ΄ λ§μ νλ nullμ΄ λ κ°λ₯μ±μ΄ μμ λ μ¬μ©
• λͺ μλ κ°μ΄ nullμ΄ μλλ©΄ λͺ μλ κ°μ κ°μ§λ Optional κ°μ²΄λ₯Ό λ°ν
• λͺ μλ κ°μ΄ nullμ΄λ©΄ λΉμ΄μλ Optional κ°μ²΄λ₯Ό λ°νν©λλ€.
// Optional μμλ κ°μ΄ μμ μλ μκ³ λΉ κ°μ²΄μΌ μλ μλ€.
Optional<String> optional = Optional.ofNullable(getString());
String result = optional.orElse("other"); // κ°μ΄ μλ€λ©΄ "other" λ₯Ό 리ν΄
Optional κ°μ²΄μ μ κ·Ό
1. get() : Optional κ°μ²΄μ μ μ₯λ κ°μ μ κ·Ό
• λ§μ½ Optional κ°μ²΄μ μ μ₯λ κ°μ΄ nullμ΄λ©΄, NoSuchElementException μμΈκ° λ°μν©λλ€.
λ°λΌμ get() λ©μλλ₯Ό νΈμΆνκΈ° μ μ isPresent() λ©μλλ₯Ό μ¬μ©νμ¬ Optional κ°μ²΄μ μ μ₯λ κ°μ΄ nullμΈμ§ μλμ§λ₯Ό λ¨Όμ νμΈν ν νΈμΆνλ κ²μ΄ μ’μ΅λλ€.
Optional<String> opt = Optional.ofNullable("μλ° Optional κ°μ²΄");
if(opt.isPresent()) {
System.out.println(opt.get()); //μλ° Optional κ°μ²΄
}
2. orElse(), orElseGet(), orElseThrow() : null λμ μ λ체ν κ°μ μ§μ
• orElse() μ μ₯λ κ°μ΄ μ‘΄μ¬νλ©΄ κ·Έ κ°μ λ°ννκ³ , κ°μ΄ μ‘΄μ¬νμ§ μμΌλ©΄ μΈμλ‘ μ λ¬λ κ°μ λ°ν
• orElseGet() μ μ₯λ κ°μ΄ μ‘΄μ¬νλ©΄ κ·Έ κ°μ λ°ννκ³ , κ°μ΄ μ‘΄μ¬νμ§ μμΌλ©΄ μΈμλ‘ μ λ¬λ λλ€ ννμμ κ²°κ³Όκ°μ λ°ν
• orElseThrow() μ μ₯λ κ°μ΄ μ‘΄μ¬νλ©΄ κ·Έ κ°μ λ°ννκ³ , κ°μ΄ μ‘΄μ¬νμ§ μμΌλ©΄ μΈμλ‘ μ λ¬λ μμΈλ₯Ό λ°μμν΄.
Optional<String> opt = Optional.empty(); // Optionalλ₯Ό nullλ‘ μ΄κΈ°νν¨.
System.out.println(opt.orElse("λΉ Optional κ°μ²΄")); //λΉ Optional κ°μ²΄
System.out.println(opt.orElseGet(String::new));
Optional μ¬μ©νκΈ°
λ¨Όμ μλ° 8 μ΄μ μλ λ€μκ³Ό κ°μ΄ null 체ν¬κ° νμνμ΅λλ€.
// μλ° 8 μ΄μ
List<String> list = getList();
List<String> listOpt = list != null ? list : new ArrayList<>();
Optional<T> κ³Ό Lambda λ₯Ό μ΄μ©νλ©΄ μ’ λ κ°λ¨νκ² ννν μ μμ΅λλ€.
List<String> listOpt = Optional.ofNullable(getList()).orElseGet(() -> new ArrayList<>());
null 체ν¬λ‘ μΈν΄ μ§μ λΆν΄μ§ μ½λμ λλ€.
User user = getUser();
if (user != null) {
Address address = user.getAddress();
if (address != null) {
String street = address.getStreet();
if (street != null) {
return street;
}
}
}
return "μ£Όμ μμ";
map λ©μλ
• κ°μ΄ null μλ κ²½μ° : mapper λ₯Ό μ΄μ©ν΄ κ³μ°ν κ°μ μ μ₯νλ Optional κ°μ²΄λ₯Ό 리ν΄ν©λλ€.
• κ°μ΄ null μΈ κ²½μ° : λΉ Optional κ°μ²΄λ₯Ό 리ν΄ν©λλ€.
public<U> Optional<U> map(Function<? super T, ? extends U> mapper)
public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper)
map λ©μλλ₯Ό μ΄μ©ν΄μ κ°λ¨νκ² ννν΄λ³΄κ² μ΅λλ€.
Optional<User> user = Optional.ofNullable(getUser());
Optional<Address> address = user.map(User::getAddress);
Optional<String> street = address.map(Address::getStreet);
String result = street.orElse("μ£Όμ μμ");
// λ€μκ³Ό κ°μ΄ μΆμ½ν΄μ μΈ μ μλ€.
user.map(User::getAddress)
.map(Address::getStreet)
.orElse("μ£Όμ μμ");
+ Optionalμ νΉμ±μ μλͺ»μ¬μ©νλ©΄ μμ€ν μ±λ₯μ΄ μ νλκΈ°λ νκΈ° λλ¬Έμ nullμ΄ λ°μν κ°λ₯μ±μ΄ μμ£Ό λμ κ²½μ°μ μ¬μ©νλ κ²μ΄ μ’λ€κ³ ν©λλ€.
νμ΅μ λ§μ΄ λμμ΄ λ λΈλ‘κ·Έ λ§ν¬λ₯Ό μ°Έμ‘°νμ΅λλ€. π
μ°Έμ‘° λ° μΆμ²