Java - Optional 사용 방법 및 예제

Java의 Optional의 기본적인 사용 방법을 소개하고, Optional이 제공하는 다양한 함수를 소개합니다.

1. Optional

Optional<Type>은 단순히 어떤 객체를 wrapping하는 객체입니다. 즉, Optional은 어떤 객체를 내부에 갖고 있으며 get() 등의 메소드들을 제공합니다. 만약 Optional이 객체를 갖고 있지 않을 때는 null이 저장됩니다.

아래 예제는 문자열 객체를 갖고 있는 Optional<String>을 생성하고, Optional.get() 함수로 문자열을 출력하는 예제입니다.

  • Optional.of(obj)는 인자로 전달된 객체를 갖고 있는 Optional을 생성해주는 함수입니다.
  • Optional.get() 호출 시, Optional이 갖고 있는 객체가 리턴됩니다. 만약 문자열이 저장되지 않았다면 null이 리턴됩니다.
String string = "a string in optional";
Optional<String> opString = Optional.of(string);
System.out.println(opString.get());

Output:

a string in optional

2. 객체를 갖고 있지 않은 Optional 생성

만약 객체를 갖고 있지 않은 Optional(null을 갖고 있는)은 어떻게 생성할까요?

일단 위에서 사용한 방법으로 생성할 수는 없습니다. Optional.of(null)은 허용되지 않습니다. Optional.of()는 null이 아닌 객체만 인자로 전달할 수 있습니다.

이럴 때는 Optional.ofNullable()을 사용하여 null을 갖고 있는 Optional을 생성할 수 있습니다.

아래 예제에서 Optional.get()은 null을 리턴하기 때문에 NoSuchElementException 예외가 발생됩니다.

String nullString = null;
Optional<String> nullOpString = Optional.ofNullable(nullString);
try {
    System.out.println(nullOpString.get());
} catch (NoSuchElementException e) {
    System.out.println("No such element");
}

Output:

No such element

다른 방법으로, Optional.empty()는 null을 갖고 있는 Optional 객체를 생성합니다. 아래 예제에서도 get()은 null을 리턴하기 때문에 NoSuchElementException 예외가 발생합니다.

Optional<String> emptyOptional = Optional.empty();
try {
    System.out.println(emptyOptional.get());
} catch (NoSuchElementException e) {
    System.out.println("No such element");
}

Output:

No such element

3. Optional.isPresent()

Optional의 객체가 null이 될 수 있기 때문에, Optional에서 리턴되는 값이 null인지 항상 확인하고 사용해야 합니다.

Optional.isPresent() 함수는 Optional의 객체가 null이 아닐 때 true가 리턴되며, null인 경우 false를 리턴합니다. 이 함수를 사용하여 null에 대한 예외처리를 할 수 있습니다.

아래 예제는 isPresent()를 사용하여 객체가 null인지 체크를 하고 어떤 작업을 수행합니다.

import java.util.Optional;

public class Example {

    public static void main(String[] args) {

        String nullString = null;
        Optional<String> opString = Optional.of("a string in optional");
        Optional<String> nullOpString = Optional.ofNullable(nullString);

        if (opString.isPresent()) {
            System.out.println("opString: " + opString.get());
        }
        if (nullOpString.isPresent()) {
            System.out.println("nullOpString: " + nullOpString.get());
        }
    }
}

Output:

opString: a string in optional

4. Optional.isPresent(), 함수형 인터페이스와 함께 사용

위의 Optional.isPresent() 예제는 일반적인 자바 스타일로 구현된 예제입니다.

Optional은 Optional.ifPresent(Consumer)라는 함수형 인터페이스를 인자로 받는 함수도 제공합니다. 함수형 인터페이스를 사용하여 함수형 프로그래밍 스타일로 위의 예제와 동일한 내용을 구현할 수 있습니다.

Optional.ifPresent(Consumer)는 Optional의 객체가 null이 아닐 때 인자로 전달된 Consumer 함수를 호출합니다. 객체가 null이라면 아무것도 하지 않습니다.

아래 예제에서

  • opString은 null이 아닌 객체를 갖고 있기 때문에, Consumer 함수가 호출됩니다.
  • nullOpString는 Optional이 null을 갖고 있기 때문에 어떤 작업도 하지 않습니다.
import java.util.Optional;

public class Example {

    public static void main(String[] args) {

        String nullString = null;
        Optional<String> opString = Optional.of("a string in optional");
        Optional<String> nullOpString = Optional.ofNullable(nullString);

        opString.ifPresent(s -> System.out.println("opString: " + s));
        nullOpString.ifPresent(s -> System.out.println("nullOpString: " + s));
    }
}

Output:

opString: a string in optional

Optional.ifPresent(Consumer)는 Optional이 null을 갖고 있는 경우 아무 동작을 하지 않습니다.

5. Optional.orElse()

Optional.orElse(object)는 Optional이 갖고 있는 객체가 null이 아닐 때 객체를 리턴하며, null이면 인자로 전달된 object가 리턴됩니다.

Optional.orElse(object)를 사용하면 항상 null이 아닌 객체가 리턴되도록 할 수 있습니다.

아래 예제에서 nullOpString.orElse()가 호출되었을 때 Optional은 null을 갖고 있기 때문에 인자로 전달된 "new string from orElse"가 리턴됩니다.

import java.util.Optional;

public class Example {

    public static void main(String[] args) {

        String nullString = null;
        Optional<String> opString = Optional.of("a string in optional");
        Optional<String> nullOpString = Optional.ofNullable(nullString);

        String str = opString.orElse("new string from orElse");
        System.out.println(str);

        String str2 = nullOpString.orElse("new string from orElse");
        System.out.println(str2);
    }
}

Output:

a string in optional
new string from orElse

6. Optional.orElseGet()

Optional이 null 객체를 갖고 있을 때 예외처리를 하고 싶을 때가 있습니다.

Optional.orElseGet(Supplier)는 Optional의 객체가 null이 아니면 리턴하고, null이면 인자로 전달된 함수를 실행시킵니다.으면

Supplier는 인자가 없고 리턴 값이 있는 함수형 인터페이스로, 람다 표현식으로 구현할 수 있습니다.

아래 예제에서 nullOpString.orElseGet() 호출 시, Optional이 null을 갖고 있기 때문에 인자로 전달된 함수의 리턴 값을 리턴합니다.

import java.util.Optional;

public class Example {

    public static void main(String[] args) {

        String nullString = null;
        Optional<String> opString = Optional.of("a string in optional");
        Optional<String> nullOpString = Optional.ofNullable(nullString);

        String str3 = opString.orElseGet(() -> "new string from orElseGet");
        System.out.println(str3);

        String str4 = nullOpString.orElseGet(() -> "new string from orElseGet");
        System.out.println(str4);
    }
}

Output:

a string in optional
new string from orElseGet

7. Optional.orElseThrow()

Optional이 null을 리턴하는 경우, 예외를 발생시키고 싶을 수도 있습니다. 이럴 때 Optional.orElseThrow()를 사용할 수 있습니다.

아래 예제에서 Optional.orElseThrow() 호출 시,

  • opString의 객체는 null이 아니기 때문에, 예외가 발생하지 않고 이 객체가 리턴됩니다.
  • nullOpString의 객체는 null이기 때문에 NullPointerException이 발생합니다.
import java.util.Optional;

public class Example {

    public static void main(String[] args) {

        String nullString = null;
        Optional<String> opString = Optional.of("a string in optional");
        Optional<String> nullOpString = Optional.ofNullable(nullString);

        try {
            String str = opString.orElseThrow(NullPointerException::new);
            System.out.println(str);
        } catch (NullPointerException e) {
            System.out.println("NullPointerException");
        }

        try {
            String str = nullOpString.orElseThrow(NullPointerException::new);
            System.out.println(str);
        } catch (NullPointerException e) {
            System.out.println("NullPointerException");
        }

    }
}

Output:

a string in optional
NullPointerException

8. Optional.filter()

Optional.filter(Predicate)는 Optional이 갖고 있는 객체가 어떤 조건에 만족하는지 필터링하는 함수입니다.

filter(Predicate)는 Optional이 갖고 있는 객체에 대해서 인자로 전달된 Predicate 함수를 수행하고, Predicate의 결과가 true일 때 Optional 자신을 리턴합니다. false를 리턴하면, Empty Optional(null을 갖고 있는)을 리턴합니다.

아래 예제를 보시면, opStr2first를 포함하고 있지 않기 때문에 Empty Optional이 리턴됩니다. filtered2는 null을 갖고 있기 때문에 filtered2.ifPresent()도 false가 리턴되어 아무것도 출력하지 않습니다.

import java.util.Optional;

public class Example {

    public static void main(String[] args) {

        Optional<String> opStr1 = Optional.of("first string");
        Optional<String> opStr2 = Optional.of("second string");
        Optional<String> filtered1 = opStr1.filter(s -> s.contains("first"));
        Optional<String> filtered2 = opStr2.filter(s -> s.contains("first"));
        filtered1.ifPresent((s) -> System.out.println("result: " + s));
        filtered2.ifPresent((s) -> System.out.println("result: " + s));
    }
}

Output:

result: first string
Loading script...

Related Posts

codechachaCopyright ©2019 codechacha