如何在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");
}
};
}
因为Java不支持地图文字,所以必须始终显式地实例化和填充地图实例。
幸运的是,在Java中可以使用工厂方法来近似映射字面量的行为。
例如:
public class LiteralMapFactory {
// Creates a map from a list of entries
@SafeVarargs
public static <K, V> Map<K, V> mapOf(Map.Entry<K, V>... entries) {
LinkedHashMap<K, V> map = new LinkedHashMap<>();
for (Map.Entry<K, V> entry : entries) {
map.put(entry.getKey(), entry.getValue());
}
return map;
}
// Creates a map entry
public static <K, V> Map.Entry<K, V> entry(K key, V value) {
return new AbstractMap.SimpleEntry<>(key, value);
}
public static void main(String[] args) {
System.out.println(mapOf(entry("a", 1), entry("b", 2), entry("c", 3)));
}
}
输出:
{a=1, b=2, c=3}
这比一次创建和填充一个元素要方便得多。
第二个方法的一个优点是,你可以用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!
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来尝试这些特性。