SSAFY-Book-Study / modern-java-in-action

모던 자바 인 액션 북스터디입니다.
1 stars 10 forks source link

4 Weeks - [Optional 기본형의 존재의의와 바람직한 응용 방법] #71

Open MadCom96 opened 1 year ago

MadCom96 commented 1 year ago

문제

OptionalInt, OptionalLong, OptionalDouble가 만들어진 이유와, 흔하지 않더라도 바람직한 사용 예시가 궁금합니다.

contents - 세부 내용

책에서 포함 요소도 1개 밖에 없고, 편리한 다른 메서드를 사용할 수 없으며, 다른 Optional과 혼용할 수 없다고 나와있습니다. 그런 불편함을 감소하고도 기본형을 지원하는 이유가 있다면 무었일지 궁급합니다. 또한 이들을 사용하는 적절한 예시가 있을까요?

참고

책 385 페이지

wlwlwon commented 1 year ago
  1. OptionalInt, OptionalLong, OptionalDouble가 만들어진 이유

    • Nullable 값을 나타낼 수 있습니다.
    • Java에서는 기본 데이터 유형(int, long, double)에는 null 값을 할당할 수 없습니다. 따라서 기본 데이터 유형(int, long, double)에 대한 Nullable한 값을 나타내기 위해 만들어졌습니다.
    • Java 8 부터는 OptionalInt, OptionalLong, OptionalDouble을 사용하여 값이 없는 상태를 나타낼 수 있습니다.
  2. 책에서 포함 요소도 1개 밖에 없고, 편리한 다른 메서드를 사용할 수 없으며, 다른 Optional과 혼용할 수 없다고 나와있습니다. 그런 불편함을 감수하고도 기본형을 지원하는 이유가 있다면 무엇일지 궁금합니다. 또한 이들을 사용하는 적절한 예시가 있을까요?

    • 우선 기본형 특화 스트림(IntStream, LongStream, DoubleStream)은 여러 기본형 값들을 스트림 형태로 다루고 처리하기 위해 설계되었습니다. 이러한 스트림은 기본형 값들을 효율적으로 저장하고 다룰 수 있으며, 병렬 처리 및 스트림 연산을 통해 성능을 개선할 수 있습니다. 하지만 Optional 기본형 클래스의 최대 요소 수는 1 개이므로 Optional 기본형 특화 클래스로 성능을 개선할 수 없다고 해석했습니다.
    • Optional 대신 OptionalInt 기본형 특화 클래스를 사용하여 OptionalInt는 기본형 int 값을 저장하므로 객체 래핑과 언박싱 작업이 필요하지 않습니다. Optional<Integer>은 객체 Wrapping을 수행하고 언박싱하는 차이가 있습니다.
    • 결론적으로 박싱된 기본 타입을 담는 옵셔널은 기본 타입 자체보다 무거울 수 밖에 없습니다. 두 겹이나 감싸기 때문입니다. 그래서 자바 8에서 부터 int, double, long 전용 옵셔널 클래스를 지원하고 있습니다.

      public static void main(String[] args) {
              int value = 42; // 기본형 int 값을 가정
      
              OptionalInt optionalInt = OptionalInt.of(value); // 기본형값 저장
              Optional<Integer> optional = Optional.of(value); // Wrapping
      
              // 값이 존재하는 경우
              if (optionalInt.isPresent()) {
                  int result = optionalInt.getAsInt(); //바로 접근
                  System.out.println("Value is: " + result);
              } else {
                  System.out.println("Value is not present.");
              }
              if(optional.isPresent()) {
                  int result = optional.get().intValue(); //언박싱 수행
                  System.out.println("Value is: " + result);
              } else {
                  System.out.println("Value is not present.");
              }
          }
      /**
           * Construct an instance with the described value.
           *
           * @param value the int value to describe
           */
          private OptionalInt(int value) {
              this.isPresent = true;
              this.value = value;
          }
      
          /**
           * Returns an {@code OptionalInt} describing the given value.
           *
           * @param value the value to describe
           * @return an {@code OptionalInt} with the value present
           */
          public static OptionalInt of(int value) {
              return new OptionalInt(value);
          }
      public static <T> Optional<T> of(T value) {
              return new Optional<>(Objects.requireNonNull(value));
      }