Java 通过其内部字段获取枚举

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2780129/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 12:46:37  来源:igfitidea点击:

Get enum by its inner field

javaenums

提问by zeroed

Have enum with inner fields, kind of map.

有带有内部字段的枚举,有点像地图。

Now I need to get enum by its inner field.

现在我需要通过其内部字段获取 enum 。

Wrote this:

写了这个:

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;
    }
}

But it's not very efficient to look up through all enums each time I need to find appropriate instance.

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

Is there any other way to do the same?

有没有其他方法可以做到这一点?

采纳答案by polygenelubricants

You can use a static Map<Integer,TestEnum>with a staticinitializer that populates it with the TestEnumvalues keyed by their numberfields.

您可以将 astatic Map<Integer,TestEnum>static初始TestEnum值设定项一起使用,该初始值设定项使用由其number字段键入的值填充它。

Note that findByKeyhas been made static, and numberhas also been made final.

注意findByKey已经做出staticnumber也已经做出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"
    }
}

You can now expect findByKeyto be a O(1)operation.

您现在可以期望findByKey进行O(1)操作。

References

参考

Related questions

相关问题



Note on values()

注意 values()

The second printlnstatement in the mainmethod is revealing: values()returns a newly allocated array with every invokation! The original O(N)solution could do a little better by only calling values()once and caching the array, but that solution would still be O(N)on average.

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

回答by Espen

You should have a HashMap with the numbers as keys and the enum values as values.

你应该有一个 HashMap 以数字作为键和枚举值作为值。

This map can typically be in your repository. Then you can easily replace an int variable from the database with your preferred enum value.

此地图通常位于您的存储库中。然后,您可以轻松地将数据库中的 int 变量替换为您首选的枚举值。

If your keys (int values) are stored in a database, then I will say its bad design to carry those keys around in an enum on your business layer. If that's the case, I will recommend not to store the int value in the enum.

如果您的键(int 值)存储在数据库中,那么我会说在业务层的枚举中携带这些键的设计很糟糕。如果是这种情况,我建议不要将 int 值存储在枚举中。

回答by aioobe

One solution is to add

一种解决方案是添加

public final Test[] TESTS = { null, ONE, TWO, THREE };

public static Test getByNumber(int i) {
    return TESTS[i];
}

To the enum.

到枚举。

If the internal data is not an integer, you could have a Map which you populate in a static { ... }initializer. This map could later be used in the getByNumbermethod above.

如果内部数据不是整数,则可以在static { ... }初始化程序中填充 Map 。此映射稍后可用于上述getByNumber方法。

回答by Alexander Pogrebnyak

Although someone has suggested using Map<Integer, TestEnum>think twice about it.

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

Your original solution, especially for small enums, may be magnitudes faster than using HashMap.

您的原始解决方案,尤其是对于小型枚举,可能比使用 HashMap 快几个数量级。

HashMap will probably be not faster until your enum contains at least 30 to 40 elements.

HashMap 可能不会更快,直到您的枚举包含至少 30 到 40 个元素。

This is one case of "If it ain't broken, don't fix it".

这是“如果它没有坏,就不要修理它”的一种情况。