Java에서 Optional은 Java 8 부터 도입된 기능으로, 주로 값이 있을 수도 없을 수도 있는 상황에서 NullPointException을 방지하고 보다 명확한 코드를 작성하기 위해 사용됩니다.
Optional을 사용하지 않을때
public class MapRepository {
private final Map<String, String> map = new HashMap<>();
public MapRepository() {
map.put("key1", "value1");
}
public String getValue(String key) {
return map.get(key);
}
public Optional<String> getOptionalValue(String key) {
return Optional.ofNullable(map.get(key));
}
}
public class NullPointExceptionEx {
public static void main(String[] args) {
MapRepository mapRepository = new MapRepository();
String value = mapRepository.getValue("key2");
// NullPointException 발생
System.out.println(value.toUpperCase());
}
}
위 value.toUpperCase() 코드에서 NullPointException이 발생하게 됩니다. 이를 방지 하기 위해서는 아래 코드로 작성하면 해결이 됩니다.
// Solution
if ( value != null ) {
System.out.println(value.toUpperCase());
}
Optional을 사용 했을 경우
public class MapRepository {
private final Map<String, String> map = new HashMap<>();
public MapRepository() {
map.put("key1", "value1");
}
public Optional<String> getOptionalValue(String key) {
return Optional.ofNullable(map.get(key));
}
}
public class NullPointExceptionEx {
public static void main(String[] args) {
MapRepository mapRepository = new MapRepository();
String optionalValue = mapRepository.getOptionalValue("key2")
.orElseGet(() -> "default value");
// DEFAULT VALUE 반환
System.out.println(optionalValue.toUpperCase());
}
}
orElse
값이 존재하면 그 값을 반환하고, 없으면 지정되 기본값을 반환합니다.
주의할 점은 orElse 내부의 기본 값 코드는 Optional에 값이 있더라도 실행 됩니다.
public class MapRepository {
private final Map<String, String> map = new HashMap<>();
public MapRepository() {
map.put("key1", "value1");
}
public Optional<String> getOptionalValue(String key) {
return Optional.ofNullable(map.get(key));
}
}
public class NullPointExceptionEx {
public static void main(String[] args) {
MapRepository mapRepository = new MapRepository();
String value = mapRepository.getOptionalValue("key1").orElse(orelse());
System.out.println("value = " + value.toUpperCase());
}
private static String orelse() {
// 실행됨
String s = "orelse";
System.out.println(s);
return s;
}
}
orElseGet
값이 존재하면 그 값을 반환하고, 없으면 제공된 Supplier을 통해서 값을 생성하여 반환합니다.
orElseGet는 값이 없을때만 Suppler의 로직이 실행됩니다. 따라서 불편한 연산을 피하려면 이 메서드를 사용하는 것이 좋습니다.
public class NullPointExceptionEx {
public static void main(String[] args) {
MapRepository mapRepository = new MapRepository();
String optionalValue = mapRepository.getOptionalValue("key2")
.orElseGet(() -> "default value");
System.out.println("optionalValue = " + optionalValue.toUpperCase());
}
}
orElseThow
값이 존재하면 그 값을 반환하고, 없으면 지정된 예외를 발생합니다.
public class NullPointExceptionEx {
public static void main(String[] args) {
MapRepository mapRepository = new MapRepository();
String optionalValue = mapRepository.getOptionalValue("key2")
.orElseThrow(() -> new IllegalArgumentException("key2에 해당하는 값이 없습니다."));
}
}
isPresent
Optional 객체에 값이 존재하면 true를 반환하고 없으면 false를 반환합니다.
이 메서드는 Optional에 값이 있는지 없는지 불리언 값으로 확인할 때 사용합니다.
Optional<String> optionalName = Optional.of("Alice");
if(optionalName.isPresent()) {
System.out.println("Name is present.");
} else {
System.out.println("Name is not present.");
}
// 출력: Name is present.
ifPresent
Optional 객체에 값이 포함되어 있으면 주어진 Consumer 함수를 가 값에 대해 실행합니다.
값이 없으면 아무런 동작을 하지 않습니다.
Optional<String> optionalName = Optional.of("Alice");
optionalName.ifPresent(name -> System.out.println("Hello, " + name + "!"));
// 출력: Hello, Alice!
ifPresentOrElse
Java9 부터 Optional 클래스에 추가된 메서드 입니다. 이 메서드는 Optional 객체의 값이 있을 경우와 값이 없을 경우 실행될 액션을 동시에 지정할 수 있습니다.
ifPresentOrElse는 Optional 객체 값의 유무에 따라 다른 동작을 수행하고 싶을때 매우 유용하게 사용됩니다.
ifPresenOrElse 의 메서드 시그니쳐
void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction)
public class MapRepository {
private final Map<String, String> map = new HashMap<>();
public MapRepository() {
map.put("key1", "value1");
}
public Optional<String> getOptionalValue(String key) {
return Optional.ofNullable(map.get(key));
}
}
public class WithOptionalExampleMain {
public static void main(String[] args) {
MapRepository mapRepository = new MapRepository();
Optional<String> string = mapRepository.getOptionalValue("NOT_EXIST_KEY");
string.ifPresentOrElse(
str -> System.out.println(str.toUpperCase()),
() -> {
// Optional이 Empty일 때 실행
throw new RuntimeException("키가 존재하지 않습니다.");
}
);
}
}
'자바' 카테고리의 다른 글
의존성 ( dependency ) (0) | 2023.12.12 |
---|---|
if문 제거하기 (0) | 2023.12.12 |
Object Class (1) | 2023.12.11 |
예외 (0) | 2023.12.11 |
캡슐화 (0) | 2023.12.11 |