有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

Java枚举反向查找

因此,我有一个枚举,它不能像我预期的那样工作,需要进行一些修改:

public enum MyEnum {

    CODE000("text description comes here"),

    private final String value;

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

    MyEnum(final String value) {
        this.value = value;
    }

    public String getValue() {
        return value;

    }


    public static MyEnum fromStatus(String status) {
        return LOOKUP.get(status);
    }
}

它现在的工作方式是:

MyEnum.fromStatus("text description comes here")当然,我想换一种方式:

MyEnum.fromStatus("CODE000")返回我"text description comes here"

有人能建议我如何改变这一点吗


共 (4) 个答案

  1. # 1 楼答案

    您的键函数(MyEnum::getValue)返回的值错误。 它必须是MyEnum::name

    这将返回枚举而不是文本描述,因为映射的值的类型为MyEnum。可以通过调用枚举上的getValue来获取文本值,也可以将值存储在映射中而不是枚举中

  2. # 2 楼答案

    到目前为止,答案是使用方法valueOf。只要提供枚举常量的名称,此方法将返回枚举常量。否则将抛出一个IllegalArgumentException

    在您的问题中,您使用的是查找地图。映射(看起来像是由Guava Maps创建的)将返回非枚举常量名称null。在这种情况下,它不会抛出IllegalArgumentException。因此,这是一种不同的行为

    此外,你说:“当然我想换个方式”
    这意味着您希望按状态获取枚举,并按枚举名称获取状态

    因此,您需要有两种查找方法:

    • 状态->;枚举
    • 名称->;地位

    但是,如果您定义了您提到的两种方法,则会出现编译时错误:

      public static MyEnum fromStatus(String status) { ... }
    
      public static String fromStatus(String name) { ... }
    

    编译器无法按名称和参数区分方法。但是,即使您编写了MyEnum.fromStatus("CODE000"),实际上它是您用作参数的枚举常量名。因此,让我们通过调用第二个方法fromName来解决命名冲突。MyEnum的代码可能如下所示:

    public enum MyEnum {
    
      CODE000("text description comes here");
    
      private final String value;
    
      private static final Map<String, MyEnum> LOOKUP_ENUM = Maps.uniqueIndex(Arrays.asList(MyEnum.values()), MyEnum::getValue);
      private static final Map<String, String> LOOKUP_STATUS = Arrays.stream(MyEnum.values()).collect(Collectors.toMap(MyEnum::name, MyEnum::getValue));
    
      MyEnum(final String value) {
        this.value = value;
      }
    
      public String getValue() {
        return value;
    
      }
    
      public static MyEnum fromStatus(String status) {
        return LOOKUP_ENUM.get(status);
      }
    
      public static String fromName(String name) {
        return LOOKUP_STATUS.get(name);
      }
    
    }
    

    如果要以相同的方式按名称查找枚举常量(非枚举常量名称无例外),则需要第三个映射和第三个查找方法:

      private static final Map<String, MyEnum> LOOKUP = Maps.uniqueIndex(Arrays.asList(MyEnum.values()), MyEnum::name);
    
      public static MyEnum byName(String name) {
        return LOOKUP.get(name);
      }
    

    这项工作如下:

    System.out.println(MyEnum.fromStatus("text description comes here")); // CODE000
    System.out.println(MyEnum.fromStatus("invalid")); // null - no exception
    System.out.println(MyEnum.fromStatus(null)); // null - no exception
    
    System.out.println(MyEnum.fromName("CODE000")); // "text description comes here"
    System.out.println(MyEnum.fromName("invalid")); // null - no exception
    System.out.println(MyEnum.fromName(null)); // null - no exception
    
    System.out.println(MyEnum.byName("CODE000")); // CODE000
    System.out.println(MyEnum.byName("invalid")); // null - no exception
    System.out.println(MyEnum.byName(null)); // null - no exception
    

    如果您需要byName方法,我建议将方法fromName重命名为类似statusByName的名称,以保持它们之间的可理解性

    最后还有一个建议:
    由于查找方法可能返回null,因此我们可以返回Optional<String>/Optional<MyEnum>。这将允许立即继续处理结果

      public static Optional<MyEnum> fromStatus(String status) { ... }
      public static Optional<String> statusByName(String name) { ... }
      public static Optional<MyEnum> byName(String name) { ... }
    
  3. # 3 楼答案

    如果要通过枚举名称获取枚举值,可以使用以下函数:

    public static String fromStatus(String status) {
        MyEnum myEnum = valueOf(status);
    
        return myEnum.getValue();
    }
    
  4. # 4 楼答案

    您需要的是一个文本查找,通过调用valueOf获得:

    MyEnum code000 =  MyEnum.valueOf("CODE000");
    

    然后:

    String val = code000.getValue();
    

    请注意,如果传递给valueOf的字符串未解析为MyEnum中的枚举文字,将引发异常