java - 从 String 转换为具有大量值的 Java 枚举

标签 java enums

假设我有一个包含 100 个值的枚举。为简单起见,举个例子:

public enum code
{
    CODE_1("string1"),
    CODE_2("string2"),
    CODE_3("string3"),
    CODE_4("string4"),
    ...
}

我想创建一个公共(public)方法来将已知格式的字符串(如“string1”、“string2”...)转换为适当的枚举值 CODE_1、CODE_2... 通常这是通过遍历所有值来完成的,如果找到匹配项,则返回该枚举值。 (详情可见in this question。)

但是,我担心定期循环所有值。这可能是一个巨大的瓶颈吗?如果不是 100 个元素,而是 1000 个呢?

作为我自己的练习,我尝试使用静态映射优化此查找,它可以确保给定任何字符串的 O(1) 查找时间。我喜欢这个额外的噱头,但如果确实有必要,我只想将它包含在我的代码中。您对使用迭代法与 map 法有何想法和发现?

public enum Code
{
    ...
    //enum values
    ...


    //The string-to-Code map
    private static final Map<String,Code> CODE_MAP = populateMap();

    private static Map<String,Code> populateMap()
    {
        Map<String,Code> map = new HashMap<String,Code>();

        for(Code c : Code.values())
        {
            map.put(c.getCode(), c);
        }

        return map;
    }


    private String code;

    private Code(String code)
    {
        this.code = code;
    }

    public String getCode()
    {
        return this.code;
    }

    public Code convertFromString(String code)
    {
        //assume that the given string is actually a key value in the map

        return (Code) CODE_MAP.get(code);
    }
}

最佳答案

你想要一个 Map<String, Code> ,但是如何整齐地填充它?枚举不允许您在初始化枚举实例之前初始化静态字段,但有一个巧妙的小技巧,称为 Initialization-on-demand holder idiom ,这使得使用此功能所需的静态初始化映射很容易实现:

public enum Code {
    CODE_1("string1"),
    CODE_2("string2"),
    CODE_3("string3"),
    // etc
    ;

    private static class Holder {
        static Map<String, Code> CODE_MAP = new HashMap<>();
    }

    private final String code;

    private Code(String code) {
        this.code = code;
        Holder.CODE_MAP.put(code, this);
    }

    public String getCode() {
        return this.code;
    }

    public Code convertFromString(String code) {
        return Holder.CODE_MAP.get(code);
    }
}

这是因为类加载器在初始化枚举类之前初始化了内部静态类,因此在枚举实例初始化期间分配映射准备加载。

没有循环。没有特殊的代码来加载 map (在构造函数中完成)。最少的代码。

关于java - 从 String 转换为具有大量值的 Java 枚举,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27703119/

相关文章:

java - JGit:我可以在不检查的情况下找出 Git 存储库中是否存在特定标签吗?

java - 处理请求后数据持久保存在hibernate的session对象中

enums - 枚举作为 TypeScript 中的参数

java - 使用 JOOQ 从表生成枚举类

Java:编译时的枚举值?

Java 公历输出错误的日期

java - 微服务架构

javascript - 如何使用 Java 将日期设置为 javascript 对象?

c# - 如何在 WPF 中为 [Flags] 枚举创建通用开关?

c++ - 从枚举输出的错误值