有没有这样初始化Java HashMap的方法?:
Map<String,String> test =
new HashMap<String, String>{"test":"test","test":"test"};
正确的语法是什么?我没有发现任何与此相关的信息。这可能吗?我正在寻找最短/最快的方法来将一些“最终/静态”值放在地图中,这些值永远不会改变,并且在创建地图时预先知道。
有没有这样初始化Java HashMap的方法?:
Map<String,String> test =
new HashMap<String, String>{"test":"test","test":"test"};
正确的语法是什么?我没有发现任何与此相关的信息。这可能吗?我正在寻找最短/最快的方法来将一些“最终/静态”值放在地图中,这些值永远不会改变,并且在创建地图时预先知道。
当前回答
使用Java 8或更低版本
您可以使用静态块用一些值初始化映射。例子:
public static Map<String,String> test = new HashMap<String, String>
static {
test.put("test","test");
test.put("test1","test");
}
使用Java 9或更高版本
在声明时,可以使用Map.of()方法用一些值初始化映射。例子:
public static Map<String,String> test = Map.of("test","test","test1","test");
其他回答
使用Java 8或更低版本
您可以使用静态块用一些值初始化映射。例子:
public static Map<String,String> test = new HashMap<String, String>
static {
test.put("test","test");
test.put("test1","test");
}
使用Java 9或更高版本
在声明时,可以使用Map.of()方法用一些值初始化映射。例子:
public static Map<String,String> test = Map.of("test","test","test1","test");
没有直接的方法可以做到这一点——截至2021,Java没有Map文字(然而,我认为它们是为Java8提出的,但没有实现)。
有些人喜欢这样:
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");
如果测试映射是实例变量,请将初始化放在构造函数或实例初始值设定项中:
Map<String,String> test = new HashMap<String, String>();
{
test.put("test","test");
test.put("test1","test2");
}
如果测试映射是类变量,请将初始化放在静态初始值设定项中:
static Map<String,String> test = new HashMap<String, String>();
static {
test.put("test","test");
test.put("test1","test2");
}
如果你希望你的映射永远不变,你应该在初始化后用Collections.unmodifiedMap(…)包装你的映射。你也可以在静态初始化器中这样做:
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);
}
(我不确定你现在是否能让考试成为最终……试试看,然后在这里报告。)
从Java9开始,您还拥有Map.of(…)和Map.entries()语法,正如yankee的回答所解释的。
所有版本
如果您恰好需要一个条目:Collections.singletonMap(“key”,“value”)。
对于Java版本9或更高版本:
是的,这现在是可能的。在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")
);
在上面的示例中,test和test2都是相同的,只是表示Map的方式不同。Map.of方法最多为映射中的十个元素定义,而Map.ofEntries方法没有这样的限制。
注意,在这种情况下,生成的映射将是一个不可变的映射。如果希望映射是可变的,可以再次复制它,例如使用mutableMap=newHashMap<>(map.of(“a”,“b”));。还要注意,在这种情况下,键和值不能为空。
(另见JEP 269和Javadoc)
对于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;
}
如果只需要放置一个键值对,可以使用Collections.singletonMap(key,value);
这是一种方式。
Map<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);
ImmutableMap.of最多可用于5个条目。否则,使用builder:source。