如何在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");
}
};
}
即使使用Guava很好的ImmutableMap类,有时我也想流畅地构建一个可变映射。发现自己想要避免静态块和匿名子类型的东西,当Java 8出现时,我写了一个小库来帮助我,叫做Fluent。
// simple usage, assuming someMap is a Map<String, String> already declared
Map<String, String> example = new Fluent.HashMap<String, String>()
.append("key1", "val1")
.append("key2", "val2")
.appendAll(someMap);
与Java 8接口默认我可以实现Fluent。所有标准Java Map实现的Map方法(例如HashMap, ConcurrentSkipListMap,…)等等),没有乏味的重复。
不可修改的地图也很简单。
Map<String, Integer> immutable = new Fluent.LinkedHashMap<String, Integer>()
.append("one", 1)
.append("two", 2)
.append("three", 3)
.unmodifiable();
参见https://github.com/alexheretic/fluent获取源代码、文档和示例。
我还没有在任何答案中看到我使用的方法(并且已经逐渐喜欢上了),所以这里是:
我不喜欢使用静态初始化器,因为它们很笨拙,
我不喜欢匿名类,因为它为每个实例创建一个新类。
相反,我更喜欢这样的初始化:
map(
entry("keyA", "val1"),
entry("keyB", "val2"),
entry("keyC", "val3")
);
不幸的是,这些方法不是标准Java库的一部分,
所以你需要创建(或使用)一个实用程序库,它定义了以下方法:
public static <K,V> Map<K,V> map(Map.Entry<K, ? extends V>... entries)
public static <K,V> Map.Entry<K,V> entry(K key, V val)
(你可以使用'import static'来避免在方法名前加上前缀)
我发现为其他集合(list、set、sortedSet、sortedMap等)提供类似的静态方法很有用。
它不像json对象初始化那样好,但就可读性而言,这是朝着那个方向迈出的一步。