如何在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");
}
};
}
我会用:
public class Test {
private static final Map<Integer, String> MY_MAP = createMap();
private static Map<Integer, String> createMap() {
Map<Integer, String> result = new HashMap<>();
result.put(1, "one");
result.put(2, "two");
return Collections.unmodifiableMap(result);
}
}
它避免了匿名类,我个人认为这是一种糟糕的风格,并避免
它使地图的创建更加明确
它使地图不可修改
因为MY_MAP是常量,所以我把它命名为常量
和往常一样,apache-commons有合适的方法MapUtils。putAll(地图、对象[]):
例如,要创建一个彩色地图:
Map<String, String> colorMap = MapUtils.putAll(new HashMap<String, String>(), new String[][] {
{"RED", "#FF0000"},
{"GREEN", "#00FF00"},
{"BLUE", "#0000FF"}
});
我做了一些不同的事情。不是最好的,但对我有用。也许它可以被“泛化”。
private static final Object[][] ENTRIES =
{
{new Integer(1), "one"},
{new Integer(2), "two"},
};
private static final Map myMap = newMap(ENTRIES);
private static Map newMap(Object[][] entries)
{
Map map = new HashMap();
for (int x = 0; x < entries.length; x++)
{
Object[] entry = entries[x];
map.put(entry[0], entry[1]);
}
return map;
}
我强烈建议使用“双大括号初始化”风格而不是静态块风格。
有人可能会说他们不喜欢匿名类、开销、性能等。
但我更多考虑的是代码的可读性和可维护性。从这个角度来看,我认为双大括号是一种比静态方法更好的代码风格。
元素是嵌套的和内联的。
它更偏向于面向对象,而不是程序性的。
性能影响非常小,可以忽略不计。
更好的IDE大纲支持(而不是许多匿名的静态{}块)
你节省了几行评论来给他们带来关系。
从异常和字节码优化器防止未初始化对象的可能的元素泄漏/实例导致。
不用担心静态块的执行顺序。
此外,如果你知道匿名类的GC,你总是可以通过使用新的HashMap(Map Map)将其转换为普通的HashMap。
你可以这样做,直到你遇到另一个问题。如果你这样做,你应该使用完全另一种编码风格(例如,没有静态的,工厂类)。
即使使用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获取源代码、文档和示例。