如何直接初始化一个HashMap(以字面的方式)?

有没有像这样初始化一个Java HashMap的方法?

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

什么是正确的语法? 我还没有发现任何关于这个。 这可能吗? 我正在寻找最短/最紧凑的方法,将一些“最终/静态”值放入一张永不改变的地图中,并在创build地图时提前知道。

不,您将不得不手动添加所有元素。 你可以使用一个静态初始化器:

 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中添加了一些工厂方法,也可以用来简化地图的创build:

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

在上面的例子中, testtest2都是一样的,只是用不同的expression方式。 Map.of方法在地图中最多可以定义10个元素,而Map.ofEntries方法则没有这个限制。

请注意,在这种情况下,生成的地图将是不可变的地图。 如果你想映射是可变的,你可以复制它,例如使用mutableMap = new HashMap<>(Map.of("a", "b"));

(另见JEP 269和Javadoc )

这是一种方法。

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

但是,你应该小心,并确保你了解上面的代码(它会创build一个从HashMapinheritance的新类)。 因此,您应该在这里阅读更多: http ://www.c2.com/cgi/wiki?DoubleBraceInitialization,或者干脆使用番石榴:

 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个键/值对 ,否则您可以使用其构build器 :

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

  • 请注意,Guava的ImmutableMap实现不同于Java的HashMap实现(最显着的是它是不可变的,不允许空键/值)
  • 欲了解更多信息,请参阅Guava关于其不可变集合types的用户指南文章

没有直接的方法来做到这一点 – Java没有地图字面值(然而 – 我认为他们提出了Java 8)。

有些人喜欢这样的:

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

这将创buildHashMap的匿名子类,其实例初始化程序将放置这些值。 (顺便说一下,map不能包含两次相同的值,第二个将会覆盖第一个,接下来的例子我将使用不同的值。)

正常的方式是(对于一个局部variables):

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

如果你的test图是一个实例variables,把初始化放在一个构造函数或实例初始化程序中:

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

如果你的test图是一个类variables,把初始化放在一个静态初始化程序中:

 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类和可变参数:用这个方法创build一个类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");