[java] 정적지도를 초기화하는 방법

MapJava 에서 정적 을 어떻게 초기화 합니까?

방법 1 : 정적 이니셜 라이저
방법 2 : 인스턴스 이니셜 라이저 (익명 서브 클래스) 또는 다른 방법?

각각의 장단점은 무엇입니까?

다음은 두 가지 방법을 보여주는 예입니다.

import java.util.HashMap;
import java.util.Map;

public class Test {
    private static final Map<Integer, String> myMap = new HashMap<>();
    static {
        myMap.put(1, "one");
        myMap.put(2, "two");
    }

    private static final Map<Integer, String> myMap2 = new HashMap<>(){
        {
            put(1, "one");
            put(2, "two");
        }
    };
}



답변

이 경우 인스턴스 이니셜 라이저는 단지 구문 설탕일까요? 왜 초기화하기 위해 여분의 익명 클래스가 필요한지 모르겠습니다. 그리고 생성되는 클래스가 최종 클래스이면 작동하지 않습니다.

정적 이니셜 라이저를 사용하여 불변 맵을 만들 수도 있습니다.

public class Test {
    private static final Map<Integer, String> myMap;
    static {
        Map<Integer, String> aMap = ....;
        aMap.put(1, "one");
        aMap.put(2, "two");
        myMap = Collections.unmodifiableMap(aMap);
    }
}


답변

정적, 불변의 맵을 초기화하는 구아바 방식이 마음에 듭니다 .

static final Map<Integer, String> MY_MAP = ImmutableMap.of(
    1, "one",
    2, "two"
);

보시다시피,의 편리한 팩토리 메소드 때문에 매우 간결 ImmutableMap합니다.

지도에 5 개 이상의 항목이 있으면 더 이상 사용할 수 없습니다 ImmutableMap.of(). 대신 ImmutableMap.builder()다음 줄을 따라 시도하십시오 .

static final Map<Integer, String> MY_MAP = ImmutableMap.<Integer, String>builder()
    .put(1, "one")
    .put(2, "two")
    // ... 
    .put(15, "fifteen")
    .build();

Guava의 불변 수집 유틸리티의 이점에 대한 자세한 내용은 Guava 사용 설명서에 설명불변 수집을 참조하십시오 .

구아바의 일부는 Google 컬렉션 이라고 불 렸습니다 . Java 프로젝트에서이 라이브러리를 아직 사용하지 않는 경우 시도해 보는 것이 좋습니다. Guava는 다른 SO 사용자가 동의 한대로 Java 용으로 가장 인기 있고 유용한 무료 타사 라이브러리 중 하나가되었습니다 . (만약 당신이 처음이라면, 그 링크 뒤에는 훌륭한 학습 자료가 있습니다.)


업데이트 (2015) : Java 8의 경우 구아바 접근 방식이 다른 것보다 깨끗하기 때문에 여전히 사용합니다. 구아바 의존성을 원하지 않으면 평범한 오래된 init 메소드를 고려하십시오 . 2 차원 배열과 Stream API 가 있는 해킹 은 나에게 묻는다면 꽤 추악하고 키와 값이 같은 유형이 아닌 Map을 만들어야하는 경우 (질문과 같이) 더 추악 해집니다 Map<Integer, String>.

자바 팔에 관해서 일반적으로 구아바의 미래에 관해서는, 루이 Wasserman은 이 말했다 2014 년 다시하고 [ 갱신 2016]는이 발표 된 구아바 (21)가 필요하고 적절하게 자바 (8) 지원합니다 .


업데이트 (2016) :로 Tagir Valeev 보낸 지적 , 자바 (9) 마지막으로 추가하여, 아무것도하지만, 순수한 JDK를 사용하지 않고 할이 깨끗한 것 편의 팩토리 메소드 모음을 :

static final Map<Integer, String> MY_MAP = Map.of(
    1, "one",
    2, "two"
);


답변

나는 사용할 것이다 :

public class Test {
    private static final Map<Integer, String> MY_MAP = createMap();

    private static Map<Integer, String> createMap() {
        Map<Integer, String> result = new HashMap<>();
        result.put(1, "one");
        result.put(2, "two");
        return Collections.unmodifiableMap(result);
    }
}
  1. 나는 개인적으로 나쁜 스타일이라고 생각하는 익명 클래스를 피하고 피합니다.
  2. 지도 작성을보다 명확하게합니다.
  3. 지도를 수정할 수 없게 만듭니다
  4. MY_MAP이 상수이므로 상수처럼 이름을 지정합니다.

답변

Java 5는 이보다 간단한 구문을 제공합니다.

static final Map<String , String> FLAVORS = new HashMap<String , String>() {{
    put("Up",    "Down");
    put("Charm", "Strange");
    put("Top",   "Bottom");
}};


답변

두 번째 방법의 한 가지 장점 Collections.unmodifiableMap()은 나중에 컬렉션을 업데이트하는 것이 아무것도 없도록 보장 할 수 있다는 것입니다.

private static final Map<Integer, String> CONSTANT_MAP =
    Collections.unmodifiableMap(new HashMap<Integer, String>() {{
        put(1, "one");
        put(2, "two");
    }});

 // later on...

 CONSTANT_MAP.put(3, "three"); // going to throw an exception!


답변

다음은 Java 8 단선 정적 맵 초기화 프로그램입니다.

private static final Map<String, String> EXTENSION_TO_MIMETYPE =
    Arrays.stream(new String[][] {
        { "txt", "text/plain" },
        { "html", "text/html" },
        { "js", "application/javascript" },
        { "css", "text/css" },
        { "xml", "application/xml" },
        { "png", "image/png" },
        { "gif", "image/gif" },
        { "jpg", "image/jpeg" },
        { "jpeg", "image/jpeg" },
        { "svg", "image/svg+xml" },
    }).collect(Collectors.toMap(kv -> kv[0], kv -> kv[1]));

편집 : Map<Integer, String>질문에서와 같이 초기화 하려면 다음과 같은 것이 필요합니다.

static final Map<Integer, String> MY_MAP = Arrays.stream(new Object[][]{
        {1, "one"},
        {2, "two"},
}).collect(Collectors.toMap(kv -> (Integer) kv[0], kv -> (String) kv[1]));

편집 (2) : i_am_zero에 의해 더 나은 혼합 유형 가능 버전이 있으며, 이는 new SimpleEntry<>(k, v)호출 스트림을 사용 합니다. 그 답을 확인하십시오 : https://stackoverflow.com/a/37384773/3950982


답변

Map.of Java 9 이상

private static final Map<Integer, String> MY_MAP = Map.of(1, "one", 2, "two");

자세한 내용은 JEP 269 를 참조하십시오. JDK 9는 2017 년 9 월 에 일반 공급 됩니다.