首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Java枚举反向查找最佳实践

Java枚举反向查找最佳实践
EN

Stack Overflow用户
提问于 2011-03-16 02:30:19
回答 8查看 44.2K关注 0票数 77

我在suggested on a blog上看到,在Java enum中使用getCode(int)进行“反向查找”是一种合理的方法:

代码语言:javascript
复制
public enum Status {
    WAITING(0),
    READY(1),
    SKIPPED(-1),
    COMPLETED(5);

    private static final Map<Integer,Status> lookup 
            = new HashMap<Integer,Status>();

    static {
        for(Status s : EnumSet.allOf(Status.class))
            lookup.put(s.getCode(), s);
    }

    private int code;

    private Status(int code) {
        this.code = code;
    }

    public int getCode() { return code; }

    public static Status get(int code) { 
        return lookup.get(code); 
    }
}

对我来说,静态映射和静态初始化器看起来都不是一个好主意,我的第一个想法是这样编写查找代码:

代码语言:javascript
复制
public enum Status {
    WAITING(0),
    READY(1),
    SKIPPED(-1),
    COMPLETED(5);

    private int code;

    private Status(int code) {
        this.code = code;
    }

    public int getCode() { return code; }

    public static Status get(int code) { 
        for(Status s : values()) {
            if(s.code == code) return s;
        }
        return null;
    }
}

这两种方法都有明显的问题吗?有没有推荐的方法来实现这种查找?

EN

回答 8

Stack Overflow用户

发布于 2011-03-16 02:33:08

来自谷歌GuavaMaps.uniqueIndex在构建查找地图方面非常方便。

更新:以下是在Java8中使用Maps.uniqueIndex的示例:

代码语言:javascript
复制
public enum MyEnum {
    A(0), B(1), C(2);

    private static final Map<Integer, MyEnum> LOOKUP = Maps.uniqueIndex(
                Arrays.asList(MyEnum.values()),
                MyEnum::getStatus
    );    

    private final int status;

    MyEnum(int status) {
        this.status = status;
    }

    public int getStatus() {
        return status;
    }

    @Nullable
    public static MyEnum fromStatus(int status) {
        return LOOKUP.get(status);
    }
}
票数 31
EN

Stack Overflow用户

发布于 2011-03-16 02:34:07

尽管静态映射具有较高的开销,但它很好用,因为它提供了按code进行的恒定时间查找。您的实现的查找时间随着枚举中元素的数量线性增加。对于小的枚举,这根本不会有太大的贡献。

这两种实现的一个问题是:null实际上是Status可以承担的一个隐藏的附加值。根据业务逻辑的规则,当查找“失败”时,返回实际的枚举值或抛出Exception可能是有意义的。

票数 20
EN

Stack Overflow用户

发布于 2011-03-16 02:40:41

这里有一个更快的替代方案:

代码语言:javascript
复制
public enum Status {
    WAITING(0),
    READY(1),
    SKIPPED(-1),
    COMPLETED(5);

    private int code;

    private Status(int code) {
        this.code = code;
    }

    public int getCode() { return code; }

    public static Status get(int code) {
        switch(code) {
            case  0: return WAITING;
            case  1: return READY;
            case -1: return SKIPPED;
            case  5: return COMPLETED;
        }
        return null;
    }
}

当然,如果您希望以后能够添加更多常量,那么这并不是真正可维护的。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5316311

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档