Есть ли способ инициализации Java HashMap, как это?:
Map<String,String> test =
new HashMap<String, String>{"test":"test","test":"test"};
Какой будет правильный синтаксис? Я не нашел ничего относительно этого. Это возможно? Я ищу самый короткий/быстрый способ поместить некоторые "окончательные/статические" значения в карту, которые никогда не меняются и заранее известны при создании карты.
Да, это возможно сейчас. В 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")
);
В приведенном выше примере и test
и test2
будут одинаковыми, только с разными способами выражения карты. Метод Map.of
определен Map.of
для десяти элементов на карте, в то время Map.ofEntries
метод Map.ofEntries
будет иметь такого ограничения.
Обратите внимание, что в этом случае полученная карта будет неизменной. Если вы хотите, чтобы карта была изменчивой, вы можете скопировать ее снова, например, используя mutableMap = new HashMap<>(Map.of("a", "b"));
Нет, вам нужно будет добавить все элементы вручную. Вы можете использовать инициализатор в анонимном подклассе, чтобы сделать синтаксис немного короче:
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);
Если вы разрешаете сторонним библиотекам, вы можете использовать Guava 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();
Нет прямого способа сделать это - у Java нет литералов в Карте (но я думаю, что они были предложены для Java 8).
Некоторые люди любят это:
Map<String,String> test = new HashMap<String, String>(){{
put("test","test"); put("test","test");}};
Это создает анонимный подкласс HashMap, инициализатор которого помещает эти значения. (Кстати, карта не может содержать в два раза то же самое значение, второй второй будет перезаписывать первый. Я буду использовать разные значения для следующих примеров.)
Нормальным способом будет это (для локальной переменной):
Map<String,String> test = new HashMap<String, String>();
test.put("test","test");
test.put("test1","test2");
Если ваша карта test
является переменной экземпляра, поместите инициализацию в конструктор или инициализатор экземпляра:
Map<String,String> test = new HashMap<String, String>();
{
test.put("test","test");
test.put("test1","test2");
}
Если ваша карта test
является переменной класса, поместите инициализацию в статический инициализатор:
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
final... попробовать и сообщить здесь.)
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");