通过数字 id 获取枚举的最佳方法

Mic*_*el 5 java enums

我需要创建一个包含大约 300 个值的枚举,并且能够通过 id (int) 获取其值。我目前有这个:

public enum Country {
    DE(1), US(2), UK(3);

    private int id;
    private static Map<Integer, Country> idToCountry = new HashMap<>();
    static {
        for (Country c : Country.values()) {
            idToCountry.put(c.id, c);
        }
    }

    Country(int id) {
        this.id = id;
    }

    public static Country getById(int id) {
        return idToCountry.get(id);
    }
}
Run Code Online (Sandbox Code Playgroud)

该枚举将被大量使用,所以我想知道这是否是性能方面的最佳解决方案。

我一遍又一遍地阅读了http://docs.oracle.com/javase/1.5.0/docs/guide/language/enums.html,但找不到描述何时

static {

}
Run Code Online (Sandbox Code Playgroud)

块被调用,并且如果保证这只会被调用一次。所以——是吗?

And*_*ner 2

静态初始化块在类初始化时被调用一次。它不保证被调用一次,但除非您使用类加载器做一些奇怪的事情,否则它会被调用一次。

因此,从性能角度来看,您的方法可能很好。我建议的唯一更改是使您的 fields final.


表示映射的另一种方法是将元素存储在数组(或列表)中:

Country[] countries = new Countries[maxId + 1];
for (Country country : Country.values()) {
  countries[country.id] = country;
}
Run Code Online (Sandbox Code Playgroud)

然后您可以通过元素索引查找它们:

System.out.println(countries[1]);  // DE.
Run Code Online (Sandbox Code Playgroud)

id这避免了必须装箱才能调用的性能损失idToCountry.get(Integer)

这当然要求您拥有非负 ID(理想情况下,ID 应该合理连续,以避免在国家/地区之间存储大量数据null)。