如何直接初始化HashMap(以字面方式)?所有版本对于 Java V9 或更高版本:对于直到 Java 版本 8:

有没有办法像这样初始化Java HashMap?

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

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


答案 1

所有版本

如果您碰巧只需要一个条目:有.Collections.singletonMap("key", "value")

对于 Java V9 或更高版本:

是的,现在这是可能的。在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:
import static java.util.Map.entry;    
Map<String, String> test2 = Map.ofEntries(
    entry("a", "b"),
    entry("c", "d")
);

在上面的示例中,两者将是相同的,只是具有不同的表示方式。该方法为映射中最多十个元素定义,而该方法将没有此类限制。testtest2Map.ofMap.ofEntries

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

(另请参阅 JEP 269Javadoc)

对于直到 Java 版本 8:

不,您必须手动添加所有元素。您可以在匿名子类中使用初始值设定项,以使语法更短一些:

Map<String, String> myMap = new HashMap<String, String>() {{
    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;
}

答案 2

这是一种方式。

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

ImmutableMap.of最多适用于 5 个条目。否则,请使用生成器: