如何在Java中初始化一个静态Map ?
方法一:静态初始化器
方法二:实例初始化器(匿名子类)
或
还有别的方法吗?
它们各自的优点和缺点是什么?
下面是一个例子来说明这两种方法:
import java.util.HashMap;
import java.util.Map;
public class Test {
private static final Map<Integer, String> myMap = new HashMap<>();
static {
myMap.put(1, "one");
myMap.put(2, "two");
}
private static final Map<Integer, String> myMap2 = new HashMap<>(){
{
put(1, "one");
put(2, "two");
}
};
}
JEP 269为Collections API提供了一些方便的工厂方法。该工厂方法不在当前的Java版本(即8)中,但计划在Java 9发行版中使用。
对于Map有两个工厂方法:of和ofEntries。使用of,可以交替传递键/值对。例如,为了创建一个像{age: 27, major: cs}这样的Map:
Map<String, Object> info = Map.of("age", 27, "major", "cs");
目前of有十个重载版本,因此您可以创建一个包含十个键/值对的映射。如果你不喜欢这个限制或交替键/值,你可以使用ofEntries:
Map<String, Object> info = Map.ofEntries(
Map.entry("age", 27),
Map.entry("major", "cs")
);
of和ofEntries都将返回一个不可变的Map,因此在构造之后不能更改它们的元素。您可以使用JDK 9 Early Access来尝试这些特性。
在Java 8中,过程方法也可以包装在Supplier中:
Map<String,String> m = ((Supplier<Map<String,String>>)(() -> {
Map<String,String> result = new HashMap<>();
result.put("foo","hoo");
...
return result;
)).get();
这只是一种假设的方法,但如果您确实需要一行代码,则可以派上用场。
第二个方法的一个优点是,你可以用Collections.unmodifiableMap()来包装它,以确保以后不会更新集合:
private static final Map<Integer, String> CONSTANT_MAP =
Collections.unmodifiableMap(new HashMap<Integer, String>() {{
put(1, "one");
put(2, "two");
}});
// later on...
CONSTANT_MAP.put(3, "three"); // going to throw an exception!
第二种方法(双括号初始化)被认为是一种反模式,因此我将采用第一种方法。
另一个初始化静态Map的简单方法是使用这个实用函数:
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 = mapOf(1, "value1", 2, "value2");
Map<String, String> map2 = mapOf("key1", "value1", "key2", "value2");
注意:在Java 9中你可以使用Map.of