Programing

HashMap을 직접 초기화하는 방법 (문자 그대로)?

lottogame 2020. 9. 28. 07:55
반응형

HashMap을 직접 초기화하는 방법 (문자 그대로)? [복제]


이 질문에 이미 답변이 있습니다.

다음과 같이 Java HashMap을 초기화하는 방법이 있습니까? :

Map<String,String> test = 
    new HashMap<String, String>{"test":"test","test":"test"};

올바른 구문은 무엇입니까? 나는 이것에 대해 아무것도 찾지 못했습니다. 이것이 가능한가? 절대 변경되지 않고 맵을 만들 때 미리 알려진 맵에 "최종 / 정적"값을 넣는 가장 짧고 빠른 방법을 찾고 있습니다.


Java 버전 9 이상의 경우 :

예, 지금 가능합니다. Java 9에는 맵 생성을 단순화하는 몇 가지 팩토리 메소드가 추가되었습니다.

// this works for up to 10 elements:
Map<String, String> test1 = Map.of(
    "a", "b",
    "c", "d"
);

// this works for any number of elements:
Map<String, String> test2 = Map.ofEntries(
    entry("a", "b"),
    entry("c", "d")
);

모두 위의 예에서 testtest2단지지도를 표현하는 다른 방법으로, 동일합니다. Map.of메서드는지도에서 최대 10 개의 요소에 대해 정의되지만 Map.ofEntries메서드에는 이러한 제한이 없습니다.

이 경우 결과 맵은 변경 불가능한 맵이됩니다. 맵을 변경할 수있게하려면 다시 복사 할 수 있습니다.mutableMap = new HashMap<>(Map.of("a", "b"));

( JEP 269Javadoc 참조 )

Java 버전 8까지 :

아니요, 모든 요소를 ​​수동으로 추가해야합니다. 익명의 하위 클래스에서 이니셜 라이저를 사용하여 구문을 조금 더 짧게 만들 수 있습니다.

Map<String, String> myMap = new HashMap<>() {{
        put("a", "b");
        put("c", "d");
    }};

그러나 익명의 하위 클래스는 경우에 따라 원치 않는 동작을 유발할 수 있습니다. 여기에는 다음이 포함됩니다.

  • 메모리 소비, 디스크 공간 소비 및 시작 시간을 증가시키는 추가 클래스를 생성합니다.
  • 비 정적 메서드의 경우 : 생성 메서드가 호출 된 객체에 대한 참조를 보유합니다. 즉, 생성 된 맵 객체가 참조되는 동안 외부 클래스의 객체는 가비지 수집 될 수 없으므로 추가 메모리를 차단합니다.

초기화에 함수를 사용하면 초기화 프로그램에서 맵을 생성 할 수 있지만 불쾌한 부작용을 피할 수 있습니다.

Map<String, String> myMap = createMap();

private static Map<String, String> createMap() {
    Map<String,String> myMap = new HashMap<String,String>();
    myMap.put("a", "b");
    myMap.put("c", "d");
    return myMap;
}

이것은 한 가지 방법입니다.

HashMap<String, String> h = new HashMap<String, String>() {{
    put("a","b");
}};

그러나주의해야하며 위의 코드를 이해하고 있는지 확인해야합니다 (HashMap에서 상속하는 새 클래스를 생성 함). 따라서 http://www.c2.com/cgi/wiki?DoubleBraceInitialization 에서 자세히 읽어 보거나 단순히 Guava를 사용해야합니다.

Map<String, Integer> left = ImmutableMap.of("a", 1, "b", 2, "c", 3);

If you allow 3rd party libs, you can use Guava's ImmutableMap to achieve literal-like brevity:

Map<String, String> test = ImmutableMap.of("k1", "v1", "k2", "v2");

This works for up to 5 key/value pairs, otherwise you can use its builder:

Map<String, String> test = ImmutableMap.<String, String>builder()
    .put("k1", "v1")
    .put("k2", "v2")
    ...
    .build();


  • note that Guava's ImmutableMap implementation differs from Java's HashMap implementation (most notably it is immutable and does not permit null keys/values)
  • for more info, see Guava's user guide article on its immutable collection types

There is no direct way to do this - Java has no Map literals (yet - I think they were proposed for Java 8).

Some people like this:

Map<String,String> test = new HashMap<String, String>(){{
       put("test","test"); put("test","test");}};

This creates an anonymous subclass of HashMap, whose instance initializer puts these values. (By the way, a map can't contain twice the same value, your second put will overwrite the first one. I'll use different values for the next examples.)

The normal way would be this (for a local variable):

Map<String,String> test = new HashMap<String, String>();
test.put("test","test");
test.put("test1","test2");

If your test map is an instance variable, put the initialization in a constructor or instance initializer:

Map<String,String> test = new HashMap<String, String>();
{
    test.put("test","test");
    test.put("test1","test2");
}

If your test map is a class variable, put the initialization in a static initializer:

static Map<String,String> test = new HashMap<String, String>();
static {
    test.put("test","test");
    test.put("test1","test2");
}

If you want your map to never change, you should after the initialization wrap your map by Collections.unmodifiableMap(...). You can do this in a static initializer too:

static Map<String,String> test;
{
    Map<String,String> temp = new HashMap<String, String>();
    temp.put("test","test");
    temp.put("test1","test2");
    test = Collections.unmodifiableMap(temp);
}

(I'm not sure if you can now make test final ... try it out and report here.)


Map<String,String> test = new HashMap<String, String>()
{
    {
        put(key1, value1);
        put(key2, value2);
    }
};

An alternative, using plain Java 7 classes and varargs: create a class HashMapBuilder with this method:

public static HashMap<String, String> build(String... data){
    HashMap<String, String> result = new HashMap<String, String>();

    if(data.length % 2 != 0) 
        throw new IllegalArgumentException("Odd number of arguments");      

    String key = null;
    Integer step = -1;

    for(String value : data){
        step++;
        switch(step % 2){
        case 0: 
            if(value == null)
                throw new IllegalArgumentException("Null key value"); 
            key = value;
            continue;
        case 1:             
            result.put(key, value);
            break;
        }
    }

    return result;
}

Use the method like this:

HashMap<String,String> data = HashMapBuilder.build("key1","value1","key2","value2");

참고URL : https://stackoverflow.com/questions/6802483/how-to-directly-initialize-a-hashmap-in-a-literal-way

반응형