본문 바로가기
자바

Java Optional

by 이상한나라의개발자 2023. 12. 12.

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