通过其内部领域获得枚举

zer*_*oed 32 java enums

有内场,地图的枚举.

现在我需要通过其内部领域获得枚举.

写道:

package test;

/**
 * Test enum to test enum =)
 */
public enum TestEnum {
    ONE(1), TWO(2), THREE(3);

    private int number;

    TestEnum(int number) {
        this.number = number;
    }      

    public TestEnum findByKey(int i) {
        TestEnum[] testEnums = TestEnum.values();
        for (TestEnum testEnum : testEnums) {
            if (testEnum.number == i) {
                return testEnum;
            }
        }
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

但是每次我需要找到合适的实例时,查看所有枚举并不是非常有效.

有没有其他方法可以做同样的事情?

pol*_*nts 58

您可以使用static Map<Integer,TestEnum>一个static与该填充它初始化TestEnum通过键入值number的字段.

注意findByKey已经制作static,并且number已经制作完成final.

import java.util.*;

public enum TestEnum {
    ONE(1), TWO(2), SIXTY_NINE(69);

    private final int number;    
    TestEnum(int number) {
        this.number = number;
    }

    private static final Map<Integer,TestEnum> map;
    static {
        map = new HashMap<Integer,TestEnum>();
        for (TestEnum v : TestEnum.values()) {
            map.put(v.number, v);
        }
    }
    public static TestEnum findByKey(int i) {
        return map.get(i);
    }

    public static void main(String[] args) {
        System.out.println(TestEnum.findByKey(69)); // prints "SIXTY_NINE"

        System.out.println(
            TestEnum.values() == TestEnum.values()
        ); // prints "false"
    }
}
Run Code Online (Sandbox Code Playgroud)

您现在可以期待findByKey成为一项O(1)操作.

参考

相关问题


注意 values()

方法中的第二个println语句main是揭示:values()返回每个invokation的新分配的数组!O(N)通过只调用values()一次并缓存数组,原始解决方案可以做得更好,但该解决方案仍然是O(N)平均的.


Ale*_*yak 17

虽然有人建议使用Map<Integer, TestEnum>三思而后行.

您的原始解决方案,尤其是小型枚举,可能比使用HashMap更快.

在你的枚举包含至少30到40个元素之前,HashMap可能不会更快.

这是"如果没有损坏,请不要修理"的一个案例.

  • 我在枚举中使用了10个常量做了粗略的第一个基准测试.使用小的int值,我的macbook上的性能是可比的 - hashmap性能仅比线性搜索差10%左右.使用随机,较大的整数作为值,地图性能会变差,因为每个查询都需要分配一个Integer实例.我在时序循环中测试了10个成功查询和2个未找到的查询中的每一个.这远不是最终的答案,但它至少应该表明亚历山大的回答并非偏离基础.当我有机会时,我会完成并发布基准代码. (3认同)
  • 哦! 当然,在我的基准测试中,findByKey方法不会调用values().values()缓存在私有静态字段中.令人遗憾的是,values()被强制在每次调用时创建并填充一个全新的数组,因为它被声明为返回数组而不是集合类型. (3认同)