Map.of()의 매개변수가 2의 배수씩만 들어가는 이유

SionBackEnd·2023년 5월 1일
0

자바 스터디

목록 보기
20/21

소개

JDK 9부터 Map.of() 메서드를 사용할 수 있게 되었다.

하지만 신기한 점은 매개변수가 2의 배수씩만 들어간다는 것이다.

심지어 2의 배수가 아니라면 컴파일 에러가 발생한다.

이유

파라미터에 if문을 사용한것도 아닐텐데 어떻게 구현했을까?
구현되어 있는 코드를 보면 쉽게 확인 가능하다.

    /**
     * Returns an unmodifiable map containing zero mappings.
     * See <a href="#unmodifiable">Unmodifiable Maps</a> for details.
     *
     * @param <K> the {@code Map}'s key type
     * @param <V> the {@code Map}'s value type
     * @return an empty {@code Map}
     *
     * @since 9
     */
    static <K, V> Map<K, V> of() {
        return ImmutableCollections.emptyMap();
    }

    /**
     * Returns an unmodifiable map containing a single mapping.
     * See <a href="#unmodifiable">Unmodifiable Maps</a> for details.
     *
     * @param <K> the {@code Map}'s key type
     * @param <V> the {@code Map}'s value type
     * @param k1 the mapping's key
     * @param v1 the mapping's value
     * @return a {@code Map} containing the specified mapping
     * @throws NullPointerException if the key or the value is {@code null}
     *
     * @since 9
     */
    static <K, V> Map<K, V> of(K k1, V v1) {
        return new ImmutableCollections.Map1<>(k1, v1);
    }

    /**
     * Returns an unmodifiable map containing two mappings.
     * See <a href="#unmodifiable">Unmodifiable Maps</a> for details.
     *
     * @param <K> the {@code Map}'s key type
     * @param <V> the {@code Map}'s value type
     * @param k1 the first mapping's key
     * @param v1 the first mapping's value
     * @param k2 the second mapping's key
     * @param v2 the second mapping's value
     * @return a {@code Map} containing the specified mappings
     * @throws IllegalArgumentException if the keys are duplicates
     * @throws NullPointerException if any key or value is {@code null}
     *
     * @since 9
     */
    static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2) {
        return new ImmutableCollections.MapN<>(k1, v1, k2, v2);
    }

  .....
  
  
  {생략}
  
  
  .....

    /**
     * Returns an unmodifiable map containing nine mappings.
     * See <a href="#unmodifiable">Unmodifiable Maps</a> for details.
     *
     * @param <K> the {@code Map}'s key type
     * @param <V> the {@code Map}'s value type
     * @param k1 the first mapping's key
     * @param v1 the first mapping's value
     * @param k2 the second mapping's key
     * @param v2 the second mapping's value
     * @param k3 the third mapping's key
     * @param v3 the third mapping's value
     * @param k4 the fourth mapping's key
     * @param v4 the fourth mapping's value
     * @param k5 the fifth mapping's key
     * @param v5 the fifth mapping's value
     * @param k6 the sixth mapping's key
     * @param v6 the sixth mapping's value
     * @param k7 the seventh mapping's key
     * @param v7 the seventh mapping's value
     * @param k8 the eighth mapping's key
     * @param v8 the eighth mapping's value
     * @param k9 the ninth mapping's key
     * @param v9 the ninth mapping's value
     * @return a {@code Map} containing the specified mappings
     * @throws IllegalArgumentException if there are any duplicate keys
     * @throws NullPointerException if any key or value is {@code null}
     *
     * @since 9
     */
    static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
                               K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9) {
        return new ImmutableCollections.MapN<>(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5,
                                               k6, v6, k7, v7, k8, v8, k9, v9);
    }

    /**
     * Returns an unmodifiable map containing ten mappings.
     * See <a href="#unmodifiable">Unmodifiable Maps</a> for details.
     *
     * @param <K> the {@code Map}'s key type
     * @param <V> the {@code Map}'s value type
     * @param k1 the first mapping's key
     * @param v1 the first mapping's value
     * @param k2 the second mapping's key
     * @param v2 the second mapping's value
     * @param k3 the third mapping's key
     * @param v3 the third mapping's value
     * @param k4 the fourth mapping's key
     * @param v4 the fourth mapping's value
     * @param k5 the fifth mapping's key
     * @param v5 the fifth mapping's value
     * @param k6 the sixth mapping's key
     * @param v6 the sixth mapping's value
     * @param k7 the seventh mapping's key
     * @param v7 the seventh mapping's value
     * @param k8 the eighth mapping's key
     * @param v8 the eighth mapping's value
     * @param k9 the ninth mapping's key
     * @param v9 the ninth mapping's value
     * @param k10 the tenth mapping's key
     * @param v10 the tenth mapping's value
     * @return a {@code Map} containing the specified mappings
     * @throws IllegalArgumentException if there are any duplicate keys
     * @throws NullPointerException if any key or value is {@code null}
     *
     * @since 9
     */
    static <K, V> Map<K, V> of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5,
                               K k6, V v6, K k7, V v7, K k8, V v8, K k9, V v9, K k10, V v10) {
        return new ImmutableCollections.MapN<>(k1, v1, k2, v2, k3, v3, k4, v4, k5, v5,
                                               k6, v6, k7, v7, k8, v8, k9, v9, k10, v10);
    }

순간적으로 궁금증이 많이 생겼다.

10 쌍의 파라미터만 가능한건가?

-> 그렇다.. 11 쌍의 파라미터는 컴파일 에러가 일어난다. (구현이 되어있지 않기 때문에)

재귀 호출을 이용해서 사용하면 안되는건가?

-> 재귀 호출 아주 좋은 생각이라고 판단했지만, 만약 파라미터에 2의 배수의 개수가 아닌 홀수개의 파라미터가 들어간다면, 재귀 호출은 컴파일 에러가 아닌 런타임 에러가 발생할것이다...

다시 본론으로 돌아와서 만약에 나에게 파라미터를 2의 배수의 개수만 받을 수 있도록 구현하라고 지시가 내려왔다면, 오버로딩은 생각하지 못하고, 재귀호출이 코드의 중복을 줄이고, 가독성도 높일수 있다고 자부하면서 자랑을 했을것 같다.그리고 당연하게 파라미터의 개수는 2의 배수 개수만 입력할 거라고 안일하게 생각했을것 같다. 하지만, 개발자도 사람이기에 제한을 두지 않으면 결국 실수하여 런타임 에러코드를 작성하기 마련이다. 컴파일 시간이 30분씩 걸리는데, 런타임 에러가 발생한다면 앞으로 그누구도 사용하지 않을 메서드가 될 확률이 높다.
이번 학습을 통해서 자율성을 주어서 에러를 늦게 확인하는것보다 약간의 제약을 주고 컴파일 에러를 확인하게 하는 로직이 더 효율 좋은 로직이라고 느끼게 되었다.

코딩을 할때 너무 화려하게 구현하는것 보다, 실질적으로 사용할때 발생할 문제점(컴파일 에러, 런타임 에러)과 속도(재귀보다는 메서드를 바로 사용하는것이 더 빠름)를 생각하면서 원시적인 로직 작성이 더 도움이 될 수 있음을 느꼈다.

한줄평 : 다형성을 더 깊게 생각하자!

profile
많은 도움 얻어가시길 바랍니다!

0개의 댓글