如何在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是常量,所以我把它命名为常量

我强烈建议使用“双大括号初始化”风格而不是静态块风格。

有人可能会说他们不喜欢匿名类、开销、性能等。

但我更多考虑的是代码的可读性和可维护性。从这个角度来看,我认为双大括号是一种比静态方法更好的代码风格。

元素是嵌套的和内联的。 它更偏向于面向对象,而不是程序性的。 性能影响非常小,可以忽略不计。 更好的IDE大纲支持(而不是许多匿名的静态{}块) 你节省了几行评论来给他们带来关系。 从异常和字节码优化器防止未初始化对象的可能的元素泄漏/实例导致。 不用担心静态块的执行顺序。

此外,如果你知道匿名类的GC,你总是可以通过使用新的HashMap(Map Map)将其转换为普通的HashMap。

你可以这样做,直到你遇到另一个问题。如果你这样做,你应该使用完全另一种编码风格(例如,没有静态的,工厂类)。

这一个使用Apache common -lang,它很可能已经在你的类路径上了:

Map<String, String> collect = Stream.of(
        Pair.of("hello", "world"),
        Pair.of("abc", "123"),
        Pair.of("java", "eight")
).collect(Collectors.toMap(Pair::getKey, Pair::getValue));

现在Java 8已经发布了,这个问题值得重新审视。我尝试了一下——看起来也许你可以利用lambda表达式语法来获得一个非常漂亮和简洁(但类型安全)的映射文字语法,看起来像这样:

Map<String,Object> myMap = hashMap(
    bob -> 5,
    TheGimp -> 8,
    incredibleKoolAid -> "James Taylor",
    heyArnold -> new Date()
);

Map<String,Integer> typesafeMap = treeMap(
    a -> 5,
    bee -> 8,
    sea -> 13
    deep -> 21
);

未经测试的示例代码在https://gist.github.com/galdosd/10823529 会对其他人对此的看法感到好奇(这有点邪恶…)

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来尝试这些特性。