简体   繁体   English

Java枚举反向查找

[英]Java enum reverse lookup

So I have this enum that doesn't work as I expected and need some modifications: 因此,我有一个无法按预期工作的枚举,需要进行一些修改:

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

The way it works now is: 现在它的工作方式是:

MyEnum.fromStatus("text description comes here") and of course I want the other way around: MyEnum.fromStatus("text description comes here") ,当然我想MyEnum.fromStatus("text description comes here")

MyEnum.fromStatus("CODE000") to return me "text description comes here" MyEnum.fromStatus("CODE000")向我返回"text description comes here"

Can someone suggest how I can change this ? 有人可以建议我该如何更改?

What you need is a literal lookup, which you get by calling valueOf : 您需要的是一个文字查找,您可以通过调用valueOf获得:

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

And then: 接着:

String val = code000.getValue();

Please note that an exception will be raised if the string passed to valueOf doesn't resolve to an enum literal in MyEnum . 请注意,如果传递给valueOf的字符串不能解析为MyEnum的枚举常量, MyEnum

Your key function ( MyEnum::getValue ) is wrong as it returns the value. 您的键函数( MyEnum::getValue )错误,因为它返回值。 It must be MyEnum::name 它必须是MyEnum::name

This will return the enum and not the text description as the value of the map is of type MyEnum . 这将返回枚举,而不是文本描述,因为映射的值是MyEnum类型。 You can get the text value by calling getValue on the enum OR you can store the value in the map instead of the enum 您可以通过在枚举上调用getValue来获取文本值,也可以将值存储在映射中而不是枚举中

If you want to get an enum value by enum name you can use this function : 如果要通过枚举名称获取枚举值,则可以使用以下函数:

public static String fromStatus(String status) {
    MyEnum myEnum = valueOf(status);

    return myEnum.getValue();
}

The answers so far are using the method valueOf . 到目前为止,答案是使用valueOf方法。 This method will return the enum constant as long as you provide a name of an enum constant. 只要您提供枚举常量的名称,此方法将返回枚举常量。 Otherwise an IllegalArgumentException will be thrown. 否则将抛出IllegalArgumentException

In your question you're using a lookup map. 在您的问题中,您正在使用查找映射。 The Map (it looks like as it's created by Guava Maps ) will return for non-enum-constant-names null . 该地图(看起来像Guava Maps创建的Maps )将返回非枚举常量名称null It will not throw a IllegalArgumentException in such cases. 在这种情况下,它不会抛出IllegalArgumentException So it is a different behaviour. 因此,这是一种不同的行为。

In addition you say: "and of course I want the other way around" 另外,您说: “当然,我想反过来”
This means you want to get the enum by status and the status by an enums name. 这意味着您想按状态获取枚举,并按枚举名称获取状态。

Therefore you would need to have two lookup methods: 因此,您将需要具有两种查找方法:

  • status -> enum 状态->枚举
  • name -> status 名称->状态

But you would get a compile time error if you define the two methods you mentioned: 但是,如果您定义了您提到的两个方法,则会出现编译时错误:

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

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

The compiler could not distinguish the methods by name and parameter. 编译器无法通过名称和参数区分方法。 But even though you wrote MyEnum.fromStatus("CODE000") actually it's the enum constant name you are using as parameter. 但是,即使您编写了MyEnum.fromStatus("CODE000")实际上它还是您用作参数的枚举常量名称。 So let's resolve the naming conflict by calling the second method fromName . 因此,让我们通过调用第二个方法fromName解决命名冲突。 The code for MyEnum could look like this: 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);
  }

}

If you want to lookup the enum constants by it's names in the same manner (no exception on non-enum-constant-names), you need a third map and a third lookup method: 如果要以相同的方式按名称查找枚举常量(非枚举常量名称也不例外),则需要第三个映射和第三个查找方法:

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

This would work as follows: 这将如下工作:

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

If you need the byName method I would suggest to rename the method fromName to something like statusByName to keep them comprehensible apart. 如果您需要byName方法,我建议将byName方法重命名为fromName类的statusByName以使它们易于理解。

Finally one more suggestion: 最后还有一个建议:
Since the lookup methods may return null we could return Optional<String> / Optional<MyEnum> as result. 由于查找方法可能返回null我们可以返回Optional<String> / Optional<MyEnum>作为结果。 This would allow to immediately continue processing the result. 这将允许立即继续处理结果。

  public static Optional<MyEnum> fromStatus(String status) { ... }
  public static Optional<String> statusByName(String name) { ... }
  public static Optional<MyEnum> byName(String name) { ... }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM