在一个语句中同时向 HashMap 添加多个条目

我需要初始化一个常量 HashMap,并希望在一行语句中完成。避免这样的事情:

  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]

我没有找到任何例子说明如何做到这一点已经看了这么多。

200822 次浏览

你可以使用 双括号初始化,如下所示:

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

作为一个警告,请参考线程 Java“双括号初始化”的效率了解它可能具有的性能影响。

Java 没有 map 文字,所以没有很好的方法可以完全满足您的要求。

如果您需要这种类型的语法,可以考虑一些 Groovy,它与 Java 兼容并允许您这样做:

def map = [name:"Gromit", likes:"cheese", id:1234]
    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的声明(这是避免“无法访问的语句”诊断所必需的) ,从技术上讲,它只是一个语句。

你可以使用谷歌番石榴的 ImmutableMap。只要您不关心以后修改 Map (您不能调用。在使用这种方法构造之后把()放在地图上) :

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

一个有点相关的问题: 在 Maps 中使用 HashMap 的 ImmutableMap.of ()解决方案?

这里有一个简单的类,可以完成您想要的任务

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=new QuickHash(
"a", "1",
"b", "2"
);

产生 {a:1, b:2}

另一种方法是编写特殊函数,通过正则表达式从一个字符串中提取所有元素值:

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

由于 Java9,使用 Map.of(...)是可能的,如下所示:

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

这个映射是不可变的。如果你想要这个映射是可变的,你必须添加:

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

如果您不能使用 Java9,那么您只能自己编写类似的 helper 方法,或者使用第三方库(如 番石榴)为您添加该功能。

您可以将这个实用程序函数添加到一个实用程序类:

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


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

注意: 在 Java 9中可以使用 地图

映射还在 Java9中添加了工厂方法。对于多达10个条目,Map 具有重载的构造函数,它们采用成对的键和值。例如,我们可以建立一个不同城市及其人口的地图(根据谷歌在2016年10月)如下:

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 中的收集工厂方法

基于@Dakusan (定义扩展 HashMap 的类)提出的解决方案,我是这样做的:

  public static HashMap<String,String> SetHash(String...pairs) {
HashMap<String,String> rtn = new HashMap<String,String>(pairs.length/2);
for ( int n=0; n < pairs.length; n+=2 ) rtn.put(pairs[n], pairs[n + 1]);
return rtn;
}

用这种方式:

HashMap<String,String> hm = SetHash( "one","aa", "two","bb", "tree","cc");

(不确定这样做是否有任何缺点(我不是一个 Java 开发人员,只是需要用 Java 完成一些任务) ,但它很有效,而且在我看来很舒服。)