수색…


소개

Optional 은 null이 아닌 값을 포함하거나 포함하지 않을 수있는 컨테이너 객체입니다. 값이 있으면 isPresent()true 를 반환하고 get() 은 값을 반환합니다.

값이 없으면 기본값을 반환하는 ifPresent() 와 값이 있으면 코드 블록을 실행하는 orElse() 와 같이 포함 된 값의 존재 여부에 따라 추가 메서드가 제공됩니다.

통사론

  • Optional.empty () // 빈 선택적 인스턴스를 만듭니다.
  • Optional.of (value) // 지정된 null이 아닌 값으로 Optional을 반환합니다. 건네받은 값이 null의 경우, NullPointerException가 Throw됩니다.
  • Optional.ofNullable (value) // null 일 수있는 지정된 값을 사용하여 Optional을 반환합니다.

Optional가 비어있는 경우 기본값 반환

NoSuchElementException 던질 수 있기 때문에 Optional.get() 사용하지 마십시오. Optional.orElse(T)Optional.orElseGet(Supplier<? extends T>) 메서드는 Optional이 비어있는 경우 기본값을 제공하는 방법을 제공합니다.

String value = "something";

return Optional.ofNullable(value).orElse("defaultValue");
// returns "something"

return Optional.ofNullable(value).orElseGet(() -> getDefaultValue());
// returns "something" (never calls the getDefaultValue() method)
String value = null;

return Optional.ofNullable(value).orElse("defaultValue");
// returns "defaultValue"

return Optional.ofNullable(value).orElseGet(() -> getDefaultValue());
// calls getDefaultValue() and returns its results

orElseorElseGet 의 중요한 차이점은 옵션이 비어 있지 않은 경우에도 이전 옵션에 제공된 인수가 평가되는 동안 옵션이 비어있는 경우에만 후자가 평가된다는 것입니다. 따라서 orElse 는 상수에 대해서만 사용되어야하며 어떤 종류의 계산을 기반으로하는 값을 제공하지 않아야합니다.

지도

Optionalmap() 메서드를 사용하여 명시 적 null 확인을 수행하지 않고 null 일 수있는 값을 처리합니다.

( map()filter() 작업은 터미널 작업 시에만 평가되는 해당 Stream과 달리 즉시 평가됩니다.)

통사론:

public <U> Optional<U> map(Function<? super T,? extends U> mapper)

코드 예제 :

String value = null;

return Optional.ofNullable(value).map(String::toUpperCase).orElse("NONE");
// returns "NONE"
String value = "something";

return Optional.ofNullable(value).map(String::toUpperCase).orElse("NONE");
// returns "SOMETHING"

맵핑 함수가 널 (NULL)을 리턴 할 때 Optional.map () 은 공백 (optional )을 리턴하기 때.에, 여러 map () 조작을 널 (null) 안보 역 참조 형식으로 연결할 수 있습니다. 이를 Null 안전 체인 이라고도합니다.

다음 예제를 고려하십시오.

String value = foo.getBar().getBaz().toString();

getBar , getBaztoString 하나는 NullPointerException 던질 수 있습니다.

다음은 Optional 사용하여 toString() 에서 값을 가져 오는 다른 방법입니다.

String value = Optional.ofNullable(foo)
                       .map(Foo::getBar)
                       .map(Bar::getBaz)
                       .map(Baz::toString)
                       .orElse("");

매핑 함수 중 하나가 null을 반환하면 빈 문자열을 반환합니다.

아래는 다른 예이지만 약간 다릅니다. 맵핑 함수가 널을 리턴하지 않은 경우에만 값을 인쇄합니다.

Optional.ofNullable(foo)
        .map(Foo::getBar)
        .map(Bar::getBaz)
        .map(Baz::toString)
        .ifPresent(System.out::println);

값이없는 경우 예외를 throw합니다.

사용 orElseThrow() 방법 Optional 포함 된 값을 가져 오거나 설정되어 있지 않은 경우는, 예외를 throw 할 수 있습니다. 이것은 임의의 예외 유형을 허용한다는 점을 제외하면 get() 을 호출하는 것과 유사합니다. 이 메소드는 던져 질 예외를 리턴해야하는 공급자를 필요로한다.

첫 번째 예제에서이 메서드는 포함 된 값을 반환하기 만합니다.

Optional optional = Optional.of("something");

return optional.orElseThrow(IllegalArgumentException::new);
// returns "something" string

두 번째 예제에서는 값이 설정되지 않았으므로이 메서드는 예외를 throw합니다.

Optional optional = Optional.empty();

return optional.orElseThrow(IllegalArgumentException::new);
// throws IllegalArgumentException

메시지가 필요한 예외를 throw하는 경우 람다 구문을 사용할 수도 있습니다.

optional.orElseThrow(() -> new IllegalArgumentException("Illegal"));

필터

filter() 는 술어와 일치하는 경우에만 값을 원한다는 것을 나타내는 데 사용됩니다.

그것을 if (!somePredicate(x)) { x = null; } .

코드 예제 :

String value = null;
Optional.ofNullable(value) // nothing
        .filter(x -> x.equals("cool string"))// this is never run since value is null
        .isPresent(); // false
String value = "cool string";
Optional.ofNullable(value) // something
        .filter(x -> x.equals("cool string"))// this is run and passes
        .isPresent(); // true
String value = "hot string";
Optional.ofNullable(value) // something
        .filter(x -> x.equals("cool string"))// this is run and fails
        .isPresent(); // false

기본 숫자 형식에 선택적 컨테이너 사용

OptionalDouble , OptionalIntOptionalLong 같은 일을 Optional 하지만, 특히 기본 유형을 포장하도록 설계되었습니다 :

OptionalInt presentInt = OptionalInt.of(value);
OptionalInt absentInt = OptionalInt.empty();

숫자 유형에는 값이 있기 때문에 null에 대한 특별한 처리가 없습니다. 빈 컨테이너는 다음을 사용하여 확인할 수 있습니다.

presentInt.isPresent(); // Is true.
absentInt.isPresent(); // Is false.

마찬가지로 가치 관리를 돕기 위해 약자가 존재합니다.

// Prints the value since it is provided on creation.
presentInt.ifPresent(System.out::println);

// Gives the other value as the original Optional is empty.
int finalValue = absentInt.orElseGet(this::otherValue);

// Will throw a NoSuchElementException.
int nonexistentValue = absentInt.getAsInt();

값이있는 경우에만 코드 실행

Optional<String> optionalWithValue = Optional.of("foo");
optionalWithValue.ifPresent(System.out::println);//Prints "foo".

Optional<String> emptyOptional = Optional.empty();
emptyOptional.ifPresent(System.out::println);//Does nothing.

공급 업체를 사용하여 느슨하게 기본값 제공

일반적인 orElse 메서드는 Object 를 사용하므로 여기에 Supplier 를 제공하는 옵션 ( orElseGet 메서드)이 왜 있는지 궁금해 할 수 있습니다.

중히 여기다:

String value = "something";
return Optional.ofNullable(value)
               .orElse(getValueThatIsHardToCalculate()); // returns "something"

그것은 getValueThatIsHardToCalculate() 호출 할 것입니다. 왜냐하면 결과는 사용되지 않습니다. 왜냐하면 선택 사항은 비어 있지 않기 때문입니다.

이 처벌을 피하려면 공급자에게 공급해야합니다.

String value = "something";
return Optional.ofNullable(value)
               .orElseGet(() -> getValueThatIsHardToCalculate()); // returns "something"

이 방법은 getValueThatIsHardToCalculate() Optional 이 비어있는 경우에만 호출됩니다.

플랫 맵

flatMapmap 과 비슷합니다. 차이점은 다음과 같이 javadoc에 의해 설명됩니다.

이 메소드는 map(Function) 과 유사하지만 제공된 매퍼는 결과가 이미 OptionalflatMap 이며, 호출 된 경우 flatMap 은 추가로 Optional 래핑하지 않습니다.

당신이 반환하는 메서드 호출 체인 즉, Optional 사용하여, Optional.flatMap 중첩 만드는 것을 피한다 Optionals .

예를 들어, 다음 클래스가 제공됩니다.

public class Foo {
    Optional<Bar> getBar(){
        return Optional.of(new Bar());
    }
}

public class Bar {
}

Optional.map 을 사용하면 중첩 된 Optional 을 얻을 수 있습니다. ie Optional<Optional<Bar>> .

Optional<Optional<Bar>> nestedOptionalBar =
    Optional.of(new Foo())
        .map(Foo::getBar);

그러나 Optional.flatMap 을 사용하면 간단한 Optional 을 얻을 수 있습니다. ie Optional<Bar> .

Optional<Bar> optionalBar =
    Optional.of(new Foo())
        .flatMap(Foo::getBar);


Modified text is an extract of the original Stack Overflow Documentation
아래 라이선스 CC BY-SA 3.0
와 제휴하지 않음 Stack Overflow