IT

Java 8-Optional.flatmap과 Optional.map의 차이점

lottoking 2020. 6. 28. 18:02
반응형

Java 8-Optional.flatmap과 Optional.map의 차이점


무엇 이러한 두 가지 방법의 차이는 다음과 같습니다 Optional.flatMap()Optional.map()?

예를 들어 주시면 감사하겠습니다.


사용 map하는 기능은 당신이 필요로하는 개체 또는 반환하는 경우 flatMap함수가 반환하는 경우를 Optional. 예를 들면 다음과 같습니다.

public static void main(String[] args) {
  Optional<String> s = Optional.of("input");
  System.out.println(s.map(Test::getOutput));
  System.out.println(s.flatMap(Test::getOutputOpt));
}

static String getOutput(String input) {
  return input == null ? null : "output for " + input;
}

static Optional<String> getOutputOpt(String input) {
  return input == null ? Optional.empty() : Optional.of("output for " + input);
}

두 인쇄 문 모두 같은 것을 인쇄합니다.


둘 다 옵션 유형에서 무언가에 이르기까지 기능을 수행합니다.

map()당신이 가진 옵션에 "있는 그대로 "기능을 적용합니다 :

if (optional.isEmpty()) return Optional.empty();
else return Optional.of(f(optional.get()));

함수가 함수 인 경우 어떻게됩니까 T -> Optional<U>?
결과는 이제 Optional<Optional<U>>!

그게 무엇 flatMap()에 관한 것입니다 : 함수가 이미를 반환하는 경우 Optional, flatMap()조금 더 똑똑이며, 반환 이중 포장을하지 않습니다 Optional<U>.

두 개의 관용구 구성 : mapflatten.


참고 :-아래는 맵 및 플랫 맵 기능의 예입니다. 그렇지 않은 경우 선택 사항은 주로 반환 유형으로 만 사용하도록 설계되었습니다.

이미 알고 있듯이 Optional은 단일 객체를 포함하거나 포함하지 않을 수있는 일종의 컨테이너이므로 null 값을 예상하는 모든 위치에서 사용할 수 있습니다 (옵션을 올바르게 사용하면 NPE가 표시되지 않을 수 있음). 예를 들어 null이 가능한 person 객체를 예상하는 메소드가있는 경우 다음과 같이 메소드를 작성하려고 할 수 있습니다.

void doSome(Optional<Person> person){
  /*and here you want to retrieve some property phone out of person
    you may write something like this:
  */
  Optional<String> phone = person.map((p)->p.getPhone());
  phone.ifPresent((ph)->dial(ph));
}
class Person{
  private String phone;
  //setter, getters
}

여기서는 선택적 유형으로 자동 래핑 된 문자열 유형을 반환했습니다.

개인 클래스가 다음과 같이 보이면 전화도 선택 사항입니다.

class Person{
  private Optional<String> phone;
  //setter,getter
}

이 경우 맵 함수를 호출하면 반환 된 값이 Optional에 래핑되고 다음과 같은 결과가 나타납니다.

Optional<Optional<String>> 
//And you may want Optional<String> instead, here comes flatMap

void doSome(Optional<Person> person){
  Optional<String> phone = person.flatMap((p)->p.getPhone());
  phone.ifPresent((ph)->dial(ph));
}

PS; Never call get method (if you need to) on an Optional without checking it with isPresent() unless you can't live without NullPointerExceptions.


What helped me was a look at the source code of the two functions.

Map - wraps the result in an Optional.

public<U> Optional<U> map(Function<? super T, ? extends U> mapper) {
    Objects.requireNonNull(mapper);
    if (!isPresent())
        return empty();
    else {
        return Optional.ofNullable(mapper.apply(value)); //<--- wraps in an optional
    }
}

flatMap - returns the 'raw' object

public<U> Optional<U> flatMap(Function<? super T, Optional<U>> mapper) {
    Objects.requireNonNull(mapper);
    if (!isPresent())
        return empty();
    else {
        return Objects.requireNonNull(mapper.apply(value)); //<---  returns 'raw' object
    }
}

  • Optional.map():

Takes every element and if the value exists, it is passed to the function:

Optional<T> optionalValue = ...;
Optional<Boolean> added = optionalValue.map(results::add);

Now added has one of three values: true or false wrapped into an Optional , if optionalValue was present, or an empty Optional otherwise.

If you don't need to process the result you can simply use ifPresent(), it doesn't have return value:

optionalValue.ifPresent(results::add); 
  • Optional.flatMap():

Works similar to the same method of streams. Flattens out the stream of streams. With the difference that if the value is presented it is applied to function. Otherwise, an empty optional is returned.

You can use it for composing optional value functions calls.

Suppose we have methods:

public static Optional<Double> inverse(Double x) {
    return x == 0 ? Optional.empty() : Optional.of(1 / x);
}

public static Optional<Double> squareRoot(Double x) {
    return x < 0 ? Optional.empty() : Optional.of(Math.sqrt(x));
}

Then you can compute the square root of the inverse, like:

Optional<Double> result = inverse(-4.0).flatMap(MyMath::squareRoot);

or, if you prefer:

Optional<Double> result = Optional.of(-4.0).flatMap(MyMath::inverse).flatMap(MyMath::squareRoot);

If either the inverse() or the squareRoot() returns Optional.empty(), the result is empty.

참고URL : https://stackoverflow.com/questions/30864583/java-8-difference-between-optional-flatmap-and-optional-map

반응형