Как непосредственно инициализировать HashMap (в буквальном смысле)? [дубликат]


этот вопрос уже есть ответ здесь:

есть ли какой-то способ инициализации Java HashMap, как это?:

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

каков будет правильный синтаксис? Я ничего не нашел по этому поводу. Это возможно? Я ищу самый короткий/быстрый способ поместить некоторые "окончательные / статические" значения на карту, которые никогда не меняются и известны заранее при создании карты.

6 755

6 ответов:

нет, вам придется добавить все элементы вручную. Вы можете использовать статический инициализатор хотя:

public class Demo
{
    private static final Map<String, String> myMap;
    static
    {
        myMap = new HashMap<String, String>();
        myMap.put("a", "b");
        myMap.put("c", "d");
    }
}

обратите внимание, что использование функции для инициализации будет делать то же самое, но может улучшить читаемость кода:

public class Demo
{
    private static final 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;
    }
}

Java 9

в Java 9 добавлены несколько фабричных методов, которые также могут быть использованы для упрощения создания карт:

public class Demo {
    private static final Map<String, String> test = Map.of("a", "b", "c", "d");
    private static final Map<String, String> test2 = Map.ofEntries(
        entry("a", "b"),
        entry("c", "d")
    );
}

в примере выше оба test и test2 будет то же самое, только с различные способы выражения карты. Элемент Map.of метод определяется для до десяти элементов на карте, в то время как Map.ofEntries метод не будет иметь такого ограничения.

обратите внимание, что в этом случае результирующая карта будет неизменную карту. Если вы хотите, чтобы карта была изменчивой, вы можете скопировать ее снова, например, используя mutableMap = new HashMap<>(Map.of("a", "b"));

(см. Также JEP 269 и документация)

Это один из способов.

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

однако, вы должны быть осторожны и убедитесь, что вы понимаете приведенный выше код (он создает новый класс, который наследует от HashMap). Поэтому, вы должны прочитать больше здесь: http://www.c2.com/cgi/wiki?DoubleBraceInitialization или просто использовать гуава:

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

Если вы разрешаете сторонние библиотеки, вы можете использовать гуавы ' s ImmutableMap для достижения буквальной краткости:

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

это работает до 5 пар ключ / значение, в противном случае вы можете использовать строитель:

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


  • обратите внимание, что гуава ImmutableMap реализация отличается от Java HashMap реализация (в первую очередь она неизменна и делает не разрешать нулевые ключи / значения)
  • для получения дополнительной информации см. статью руководства пользователя Guava на its неизменяемые типы коллекций

нет прямого способа сделать это - Java не имеет литералов карт (пока-я думаю, что они были предложены для Java 8).

некоторые люди, как этот:

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

это создает анонимный подкласс HashMap, инициализатор экземпляра которого помещает эти значения. (Кстати, карта не может содержать дважды одно и то же значение, ваш второй put перезапишет первый. Я буду использовать различные значения для следующих примеров.)

нормальный способ будет таким (для местного переменная):

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

если test map-это переменная экземпляра, поместите инициализацию в конструктор или инициализатор экземпляра:

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

если test map-это переменная класса, поместите инициализацию в статический инициализатор:

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

если вы хотите, чтобы ваша карта никогда не менялась, вы должны после инициализации обернуть свою карту на Collections.unmodifiableMap(...). Вы можете сделать это и в статическом инициализаторе:

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);
}

(Я не уверен, что вы можете сейчас сделай test финал ... попробуйте его и сообщить здесь.)

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

альтернатива, используя простые классы Java 7 и varargs: создайте класс HashMapBuilder С помощью этого метода:

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;
}

используйте метод следующим образом:

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