programing

Java 8 - 옵션 간의 차이.플랫맵 및 옵션.map

prostudy 2022. 5. 13. 23:50
반응형

Java 8 - 옵션 간의 차이.플랫맵 및 옵션.map

이 두 방법의 차이점은 무엇인가?Optional.flatMap()그리고Optional.map()?

예를 들어주면 고맙겠다.

사용하다map함수가 필요한 개체를 반환하는 경우 또는flatMap함수가 a를 반환할 경우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>.

그것은 두 가지 기능 숙어들의 구성이다.map그리고flatten.

좋아. 중첩된 옵션과 마주할 때만 'flatMap'을 사용하면 돼.여기 그 예가 있다.

public class Person {

    private Optional<Car> optionalCar;

    public Optional<Car> getOptionalCar() {
        return optionalCar;
    }
}

public class Car {

    private Optional<Insurance> optionalInsurance;

    public Optional<Insurance> getOptionalInsurance() {
        return optionalInsurance;
    }
}

public class Insurance {

    private String name;

    public String getName() {
        return name;
    }

}

public class Test {

    // map cannot deal with nested Optionals
    public Optional<String> getCarInsuranceName(Person person) {
        return person.getOptionalCar()
                .map(Car::getOptionalInsurance) // ① leads to a Optional<Optional<Insurance>
                .map(Insurance::getName);       // ②
    }

}

스트림과 마찬가지로 옵션#map은 옵션으로 포장된 값을 반환한다.그래서 중첩된 옵션 --Optional<Optional<Insurance>. 그리고 ②에서는 보험사 인스턴스로 맵핑을 하고 싶은데, 그렇게 해서 비극이 일어난 겁니다.루트는 중첩된 옵션이다.껍데기와 상관없이 핵심 가치를 얻을 수 있다면 우리는 해낼 수 있을 것이다.그것이 플랫맵이 하는 일이다.

public Optional<String> getCarInsuranceName(Person person) {
    return person.getOptionalCar()
                 .flatMap(Car::getOptionalInsurance)
                 .map(Insurance::getName);
}

결국, 나는 네가 자바8을 체계적으로 공부하고 싶다면 너에게 자바8액션을 추천했다.

참고:- 아래는 지도와 플랫맵 기능에 대한 그림이며, 그렇지 않은 경우 옵션이란 주로 반환 유형으로만 사용하도록 설계되어 있다.

이미 알고 있는 바와 같이, 옵션이란 하나의 물체를 포함하거나 포함하지 않을 수 있는 용기의 일종이므로, null 값을 예상하는 곳이라면 어디에서나 사용할 수 있다(선택을 적절하게 사용하면 NPE를 볼 수 없다).예를 들어, 무효가 될 수 있는 대상에게 예상하는 방법이 있는 경우 다음과 같은 방법으로 작성하기를 원할 수 있다.

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
}

선택적 유형으로 자동 포장되는 문자열 유형을 반환하셨습니다.

만약 Person class가 이렇게 생겼다면, 즉 전화도 선택사항이다.

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

이 경우 지도 함수를 호출하면 Option(옵션)으로 반환된 값이 포장되어 다음과 같은 결과를 얻을 수 있다.

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; NullPointer 없이 살 수 없는 경우를 제외하고 옵션에서 (필요한 경우)가 있는 상태인지 확인하지 않고 전화 걸기 메서드(필요한 경우)를 호출하지 마십시오.예외.

나에게 도움이 된 것은 두 기능의 소스 코드를 살펴본 것이었다.

지도 - 결과를 선택사항으로 줄 바꿈.

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
    }
}

플랫맵 - '원시' 개체 반환

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():

모든 요소를 가져가고 값이 존재하는 경우 다음 함수에 전달된다.

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

Now added에는 다음 세 가지 값 중 하나가 있다.true또는false의 옵션으로 포장된 경우.optionalValue존재하거나 비어 있는 선택사항.

결과를 처리할 필요가 없는 경우 간단히 사용할 수 있다.ifPresent() 반환 값:

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

동일한 스트림 방법과 유사한 작업.냇물의 흐름을 평탄하게 하다.값이 제시되면 기능에 적용된다는 차이점을 가지고.그렇지 않으면 빈 선택사항이 반환된다.

선택적 가치 함수 호출을 구성하는 데 사용할 수 있다.

다음과 같은 방법이 있다고 가정해 보십시오.

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));
}

그러면 다음과 같은 역의 제곱근을 계산할 수 있다.

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

또는, 다음을 원하는 경우:

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

다음 중 하나라도inverse()또는 그squareRoot()돌아온다Optional.empty(), 결과는 공허하다.

자세한 내용은 아래 링크를 참조하십시오(내가 찾을 수 있는 가장 좋은 설명).

https://www.programmergirl.com/java-8-map-flatmap-difference/

지도와 플랫맵 모두 - 기능 수용지도 반환 유형()은 단일 값인 반면 플랫맵은 값의 스트림을 반환함

<R> Stream<R> map(Function<? super T, ? extends R> mapper)

<R> Stream<R> flatMap(Function<? super T, ? extends Stream<? extends R>> mapper)

그들은 같은 일을 한다.

유일한 차이점은, 바로 그 점이라는 것이다.lambda귀국의 활자는 에 의해 포장된다.Optional그렇지 않으면.

정상적인 사용의 경우,map flatMap

예:

package bj;

import java.util.Optional;

import static java.lang.System.out;

public class App {

    public static void main(String[] args) {
        out.println(Optional.of(10).map    (x ->             x * x));
        out.println(Optional.of(10).flatMap(x -> Optional.of(x * x)));
        out.println(Optional.of(10).map    (x -> Optional.of(x * x).get()));

        out.println(Optional.<Integer>empty().map    (x ->             x * x));
        out.println(Optional.<Integer>empty().flatMap(x -> Optional.of(x * x)));
        out.println(Optional.<Integer>empty().map    (x -> Optional.of(x * x).get()));
    }
}

출력:

Optional[100]
Optional[100]
Optional[100]
Optional.empty
Optional.empty
Optional.empty

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

반응형