하나의 명령문에서 한 번에 여러 항목을 HashMap에 추가


138

상수 HashMap을 초기화하고 한 줄로 수행하고 싶습니다. 이 같은 sth를 피하십시오 :

  hashMap.put("One", new Integer(1)); // adding value into HashMap
  hashMap.put("Two", new Integer(2));      
  hashMap.put("Three", new Integer(3));

목표 C에서 이와 유사합니다.

[NSDictionary dictionaryWithObjectsAndKeys:
@"w",[NSNumber numberWithInt:1],
@"K",[NSNumber numberWithInt:2],
@"e",[NSNumber numberWithInt:4],
@"z",[NSNumber numberWithInt:5],
@"l",[NSNumber numberWithInt:6],
nil] 

나는 그렇게 많은 것을 보았을 때 이것을하는 방법을 보여주는 예를 찾지 못했습니다.

답변:


259

당신은 이것을 할 수 있습니다 :

Map<String, Integer> hashMap = new HashMap<String, Integer>()
{{
     put("One", 1);
     put("Two", 2);
     put("Three", 3);
}};

11
@ user387184 그래, 그들은 "이중 괄호 이니셜 라이저"라고 부른다. 이 주제를보십시오 : stackoverflow.com/questions/924285/…
Eng.Fouad

2
방금 코드에 넣은 후 "serializable 클래스는 long 유형의 정적 final serialVersionUID 필드를 선언하지 않습니다"라는 경고 / 메시지를 얻습니다. 그냥 무시해도 될까요? 이것은 무엇을 의미 하는가? 감사
user387184

31
이 방법을 사용하지 않아야합니다. 매번 사용할 때마다 새 클래스를 생성하므로 맵을 만드는 것보다 성능 이 훨씬 떨어집니다. 참조 stackoverflow.com/questions/924285/...
티모 Türschmann

7
내가 이것을 하향 투표 한 이유는 이것이 당신이 그것을 사용할 때마다 새로운 클래스를 생성한다고 설명하지 않았기 때문입니다. 나는 사람들이 이런 식으로하는 것의 장단점을 알고 있어야한다고 생각합니다.
idungotnosn

6
@ TimoTürschmann은 이와 같은 맵의 정적 초기화가 필요한 경우 성능 페널티 를 사용할 때마다 제거되어 정적 인 것 같습니다. 변수가 정적이지 않고 이런 종류의 초기화 원한다는 다른 시간을 볼 수 없습니다 (예 : 아무도 이것을 루프에서 사용합니까?). 그래도 프로그래머는 창의적입니다.
Chris Cirefice

65

Google Guava의 ImmutableMap을 사용할 수 있습니다. 나중에 맵 수정에 신경 쓰지 않는 한 작동합니다 (이 메소드를 사용하여 맵을 생성 한 후 맵에서 .put ()을 호출 할 수 없음).

import com.google.common.collect.ImmutableMap;

// For up to five entries, use .of()
Map<String, Integer> littleMap = ImmutableMap.of(
    "One", Integer.valueOf(1),
    "Two", Integer.valueOf(2),
    "Three", Integer.valueOf(3)
);

// For more than five entries, use .builder()
Map<String, Integer> bigMap = ImmutableMap.<String, Integer>builder()
    .put("One", Integer.valueOf(1))
    .put("Two", Integer.valueOf(2))
    .put("Three", Integer.valueOf(3))
    .put("Four", Integer.valueOf(4))
    .put("Five", Integer.valueOf(5))
    .put("Six", Integer.valueOf(6))
    .build();

또한보십시오: http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ImmutableMap.html

다소 관련된 질문 : 지도의 HashMap에 대한 ImmutableMap.of () 해결 방법?


구아바는 거대합니다. 꼭 필요한 경우가 아니면 안드로이드 앱에 사용하지
않겠습니다

4
키나 값을 ImmutableMap허용하지 않도록 주의하십시오 null.
Vadzim

@ericn ProGuard를 사용하면 사용하지 않는 라이브러리의 일부를 제외 할 수 있습니다.
dimo414

55

Java 9부터는 Map.of(...)다음과 같이 사용할 수 있습니다.

Map<String, Integer> immutableMap = Map.of("One", 1, 
                                           "Two", 2, 
                                           "Three", 3);

이지도는 변경할 수 없습니다. 맵을 변경 가능하게하려면 다음을 추가해야합니다.

Map<String, Integer> hashMap = new HashMap<>(immutableMap);

Java 9를 사용할 수 없다면 비슷한 도우미 메서드를 직접 작성하거나 Guava 와 같은 타사 라이브러리를 사용하여 해당 기능을 추가해야합니다.


10 개의 항목을 추가 한 후 "방법을 확인할 수 없습니다"라는 이상한 오류가 발생합니다.이 방법으로이 버그가 발생합니까?
vikramvi

2
@vikramvi yes 문서 를 보면 Map.of상당히 힘들 기 때문에 최대 10 개의 항목 만 작성됩니다
jolivier

8

Java에는 맵 리터럴이 없으므로 원하는 것을 정확하게 수행하는 좋은 방법이 없습니다.

해당 유형의 구문이 필요한 경우 Java와 호환되고 다음을 수행 할 수있는 Groovy를 고려하십시오.

def map = [name:"Gromit", likes:"cheese", id:1234]

8

맵에는 Java 9에 팩토리 메소드가 추가되었습니다. 최대 10 개의 항목에 대해 맵에는 키와 값 쌍을 취하는 오버로드 된 생성자가 있습니다. 예를 들어 다음과 같이 다양한 도시와 인구 (2016 년 10 월 Google에 따라)의지도를 작성할 수 있습니다.

Map<String, Integer> cities = Map.of("Brussels", 1_139000, "Cardiff", 341_000);

Map의 var-args 사례는 조금 더 어려우므로 키와 값을 모두 가져야하지만 Java에서는 메소드에 두 개의 var-args 매개 변수를 사용할 수 없습니다. 따라서 일반적인 경우는 Map.Entry<K, V>객체 의 var-args 메소드를 사용하여 객체 entry()를 구성 하는 정적 메소드를 추가하여 처리됩니다. 예를 들면 다음과 같습니다.

Map<String, Integer> cities = Map.ofEntries(
    entry("Brussels", 1139000), 
    entry("Cardiff", 341000)
);

Java 9의 콜렉션 팩토리 메소드


Java 9 이상을 사용할 수 있다면 좋습니다. 또한 이러한 팩토리 메소드는 변경 불가능한 맵을 리턴합니다.
Sourabh

6

원하는 것을 성취 할 수있는 간단한 수업이 있습니다.

import java.util.HashMap;

public class QuickHash extends HashMap<String,String> {
    public QuickHash(String...KeyValuePairs) {
        super(KeyValuePairs.length/2);
        for(int i=0;i<KeyValuePairs.length;i+=2)
            put(KeyValuePairs[i], KeyValuePairs[i+1]);
    }
}

그리고 그것을 사용하려면

Map<String, String> Foo=QuickHash(
    "a", "1",
    "b", "2"
);

이 결과 {a:1, b:2}


4
    boolean x;
    for (x = false, 
        map.put("One", new Integer(1)), 
        map.put("Two", new Integer(2)),      
        map.put("Three", new Integer(3)); x;);

x( "도달 할 수없는 진술"진단을 피하는 데 필요한) 선언을 무시하면 기술적으로는 하나의 진술 일뿐입니다.


14
역겨운 해키입니다.
Micah Stairs

1
@MicahStairs-그러나 그것은 단 하나의 진술입니다.
핫 릭

2
사실이지만 이것은 프로덕션에서 우연히 만나고 싶지 않은 일종의 코드입니다.
Micah Stairs

@MicahStairs-나는 더 나빠 보았다.
핫 릭

1
Omg 오늘이 코드를 검색했습니다.이 코드는 어떻게 작동합니까? 테스트를 위해 코드에 추가했지만 내부적으로 어떻게 작동하는지 알 수 없습니다 ... :)
GOXR3PLUS

1

이 유틸리티 함수를 유틸리티 클래스에 추가 할 수 있습니다.

public static <K, V> Map<K, V> mapOf(Object... keyValues) {
    Map<K, V> map = new HashMap<>();

    for (int index = 0; index < keyValues.length / 2; index++) {
        map.put((K)keyValues[index * 2], (V)keyValues[index * 2 + 1]);
    }

    return map;
}

Map<Integer, String> map1 = YourClass.mapOf(1, "value1", 2, "value2");
Map<String, String> map2 = YourClass.mapOf("key1", "value1", "key2", "value2");

참고 : Map.ofJava 9 를 사용할 수 있습니다


-1

또 다른 접근법은 정규 표현식으로 한 문자열에서 모든 요소 값을 추출하는 특수 함수를 작성하는 것일 수 있습니다.

import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Example {
    public static void main (String[] args){
        HashMap<String,Integer> hashMapStringInteger = createHashMapStringIntegerInOneStat("'one' => '1', 'two' => '2' , 'three'=>'3'  ");

        System.out.println(hashMapStringInteger); // {one=1, two=2, three=3}
    }

    private static HashMap<String, Integer> createHashMapStringIntegerInOneStat(String str) {
        HashMap<String, Integer> returnVar = new HashMap<String, Integer>();

        String currentStr = str;
        Pattern pattern1 = Pattern.compile("^\\s*'([^']*)'\\s*=\\s*>\\s*'([^']*)'\\s*,?\\s*(.*)$");

        // Parse all elements in the given string.
        boolean thereIsMore = true;
        while (thereIsMore){
            Matcher matcher = pattern1.matcher(currentStr);
            if (matcher.find()) {
                returnVar.put(matcher.group(1),Integer.valueOf(matcher.group(2)));
                currentStr = matcher.group(3);
            }
            else{
                thereIsMore = false;
            }
        }

        // Validate that all elements in the given string were parsed properly
        if (currentStr.length() > 0){
            System.out.println("WARNING: Problematic string format. given String: " + str);
        }

        return returnVar;
    }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.