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

Java 通过其内部字段获取枚举,java,enums,Java,Enums,具有带有内部字段的枚举,类似于映射 现在我需要通过它的内部字段得到enum 他写道: 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; } pu

具有带有内部字段的枚举,类似于映射

现在我需要通过它的内部字段得到enum

他写道:

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;
    }
}
但每次我需要找到合适的实例时,查找所有枚举并不是很有效


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

您应该有一个HashMap,其中数字作为键,枚举值作为值

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


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

您可以使用带有
静态
初始值设定项的
静态映射
,该初始值设定项使用由
数字
字段键入的
TestEnum
值填充它

请注意,
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"
    }
}
import java.util.*;
公共枚举测试数{
一(1)、二(2)、六十九(69);
私人最终整数;
TestEnum(整数){
这个数字=数字;
}
私有静态最终地图;
静止的{
map=新的HashMap();
for(TestEnum v:TestEnum.values()){
地图放置(v.编号,v);
}
}
公共静态TestEnum findByKey(int i){
返回地图。获取(i);
}
公共静态void main(字符串[]args){
System.out.println(TestEnum.findByKey(69));//打印“六十九”
System.out.println(
TestEnum.values()==TestEnum.values()
);//打印“假”
}
}
您现在可以期望
findByKey
成为
O(1)
操作

工具书类
相关问题

关于
values()
main
方法中的第二条
println
语句显示:
values()
每次调用都返回一个新分配的数组!原始的
O(N)
解决方案只需调用
values()
一次并缓存数组,就可以做得更好一些,但该解决方案平均来说仍然是
O(N)

一个解决方案是添加

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

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


如果内部数据不是整数,则可以在
静态{…}
初始值设定项中填充一个映射。此映射稍后可以在上面的
getByNumber
方法中使用。

尽管有人建议使用
map
请三思

您的原始解决方案,特别是对于小枚举,可能比使用HashMap快很多

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


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

以下是通过字段查找枚举值的最方便方法:

public enum TestEnum {

  A("EXAMPLE_1", "Qwerty", 1),
  B("EXAMPLE_2", "Asdfgh", 2),
  C("EXAMPLE_3", "Zxcvbn", 3);

  private final String code;
  private final String name;
  private final Integer typeID;

  TestEnum(String code, String name, Integer typeID) {
    this.code = code;
    this.name = name;
    this.key = typeID;
  }

  public String getCode() {
    return code;
  }

  public String getName() {
    return name;
  }

  public Integer getKey() {
    return key;
  }

  public static TestEnum findValueByTypeId(Integer key) {
    return Arrays.stream(TestEnum.values()).filter(v ->
        v.getKey().equals(key)).findFirst().orElseThrow(() ->
        new Exception(String.format("Unknown TestEnum.key: '%s'", key)));
  }
}

很好的解决方案。这也是我想到的。我通常在
static{…}
中填充映射,您发布的延迟版本不是线程安全的。考虑线程A和B都在map=null之前停止。A继续并在返回前停止。B执行map=并在初始化值之前停止。然后A继续进行,并可能返回不正确的null。虽然这种情况不太可能发生,但对于多线程来说,代码仍然是不正确的。嗯,在进一步搜索之后,我稍微有点不对劲。我想这只是一个问题,如果您试图访问枚举构造函数中的静态映射。我的错,这应该是正常的。Re:“O(N)”。当N是某个可能变大的变量时,比较大操作系统是有用的。当N是我的枚举中的常量数时,我确切地知道有多少个,一个O(N^2)解决方案可能比其他人的O(logn)解决方案更好。69是如何出现的?是什么让你认为
HashMap
如此缓慢?它被初始化一次,然后比调用
values()
(每次都必须是新分配的数组;尝试
TestEnum.values()==TestEnum.values()
false
)然后遍历每个元素要快得多。@polygene润滑剂:我只做过一次经验测试。查看
HashMap.get的实现。它比OP最初的实现做得更多。不久前,我做了这个精确的测试,发现在你至少有30个元素要遍历之前,考虑哈希图是不值得的。这就是说,您的实现是完全正确的,将完成一项工作。我认为30-40可能是夸大了,但我将尝试对此进行基准测试。我认为这个答案基本上是正确的,但对于这个数字的一些选择,需要指出。我已经用枚举中的10个常量做了一个粗略的第一个基准测试。对于较小的int值,我的macbook上的性能相当——hashmap的性能仅比线性搜索差10%左右。使用随机的、较大的整数作为值,映射性能会变得更差,因为每个查询都需要分配一个整数实例。我在计时循环中测试了10个成功查询和2个未找到的查询。这远不是最终的答案,但至少应该表明亚历山大的答案并没有太离谱。如果有机会,我会完成并发布基准代码。哦!当然,在我的基准测试中,findByKey方法不调用values()。values()缓存在私有静态字段中。很遗憾,values()在每次调用时都被迫创建并填充一个全新的数组,因为它被声明为返回一个数组而不是集合类型。您能详细说明一下吗?对我来说,在Java端使用
enum
作为数据库级别的
int
表示的枚举似乎很自然。什么使使用
enum
成为一种糟糕的设计?您有什么建议?@Pascal:在分层应用程序中,您的服务