java枚举字符串匹配

java枚举字符串匹配,java,enums,Java,Enums,我的枚举如下: public enum ServerTask { HOOK_BEFORE_ALL_TASKS("Execute"), COPY_MASTER_AND_SNAPSHOT_TO_HISTORY("Copy master db"), PROCESS_CHECKIN_QUEUE("Process Check-In Queue"), ... } 我还有一个字符串(比方说string=“Execute”),我想根据它与枚举中的哪个字符串匹配,将其生成ServerTask枚举的实例。有没有

我的枚举如下:

public enum ServerTask {

HOOK_BEFORE_ALL_TASKS("Execute"),
COPY_MASTER_AND_SNAPSHOT_TO_HISTORY("Copy master db"),
PROCESS_CHECKIN_QUEUE("Process Check-In Queue"),
...
}

我还有一个字符串(比方说string=“Execute”),我想根据它与枚举中的哪个字符串匹配,将其生成ServerTask枚举的实例。有没有比在要匹配的字符串和枚举中的每个项之间进行相等性检查更好的方法?由于我的枚举相当大,这似乎需要很多if语句创建静态反向查找映射

public enum ServerTask {

  HOOK_BEFORE_ALL_TASKS("Execute"),
  COPY_MASTER_AND_SNAPSHOT_TO_HISTORY("Copy master db"),
  PROCESS_CHECKIN_QUEUE("Process Check-In Queue"),
  ...
  FINAL_ITEM("Final item");

  // For static data always prefer to use Guava's Immutable library
  // http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ImmutableMap.html

  static ImmutableMap< String, ServerTask > REVERSE_MAP;

  static
  {
    ImmutableMap.Builder< String, ServerTask > reverseMapBuilder =
      ImmutableMap.builder( );

    // Build the reverse map by iterating all the values of your enum
    for ( ServerTask cur : values() )
    {
       reverseMapBuilder.put( cur.taskName, cur );
    }

    REVERSE_MAP = reverseMapBuilder.build( );
  }

  // Now is the lookup method
  public static ServerTask fromTaskName( String friendlyName ) 
  {
    // Will return ENUM if friendlyName matches what you stored
    // with enum
    return REVERSE_MAP.get( friendlyName );
  }

}
公共枚举服务器任务{
在所有任务之前挂起钩(“执行”),
将主机和快照复制到历史记录(“复制主机数据库”),
进程签入队列(“进程签入队列”),
...
最终项目(“最终项目”);
//对于静态数据,您总是喜欢使用Guava的不可变库
// http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ImmutableMap.html
静态ImmutableMap反向映射;
静止的
{
ImmutableMap.BuilderreverseMapBuilder=
ImmutableMap.builder();
//通过迭代枚举的所有值来构建反向映射
对于(服务器任务cur:values())
{
reverseMapBuilder.put(cur.taskName,cur);
}
REVERSE_MAP=reverseMapBuilder.build();
}
//现在是查找方法
publicstaticservertask fromTaskName(stringfriendlyname)
{
//如果friendlyName与存储的内容匹配,将返回枚举
//使用枚举
返回反向映射get(friendlyName);
}
}

在某种程度上,您必须迭代您拥有的整个枚举集,并且必须通过映射结构(初始填充)或基本循环将它们进行相等比较

用一个基本的循环很容易完成,所以我看不出你为什么不想走这条路。下面的代码段假定字段名为
friendlyTask

public static ServerTask forTaskName(String friendlyTask) {
    for (ServerTask serverTask : ServerTask.values()) {
        if(serverTask.friendlyTask.equals(friendlyTask)) {
            return serverTask;
        }
    }
    return null;
}
这种方法需要注意的是,数据不会存储在内部,根据实际拥有的枚举数和调用此方法的次数,它的性能会比使用映射初始化稍差


然而,这种方法是最直接的。如果你发现自己处于几百个枚举的位置(甚至超过20个对我来说是个气味),考虑一下这些枚举代表的是什么,以及应该怎么做才能把它分解多一点。

< P>如果你必须从<代码>字符串 <强>经常< /强>中获得<代码> EnUM <代码>,然后,创建一个类似于建议的反向地图可能是值得的

如果您只需执行一次或两次,那么使用单个If语句循环值可能是您的最佳选择(如的注释暗示)

但是,有一种方法可以完全不迭代这些值。如果可以确保
枚举
实例的名称及其
字符串
值相同,则可以使用:

ServerTask.valueOf("EXECUTE")
这将为您提供ServerTask.EXECUTE

有关更多信息,请参阅答案


话虽如此,我不推荐这种方法,除非您同意让实例具有与其标识符相同的字符串表示形式,并且您的应用程序是一个性能关键型应用程序,而这种应用程序通常不是

您可以编写如下方法:

static ServerTask getServerTask(String name)
{
    switch(name)
    {
         case "Execute": return HOOK_BEFORE_ALL_TASKS;
         case "Copy master db": return COPY_MASTER_AND_SNAPSHOT_TO_HISTORY;
         case "Process Check-In Queue": return PROCESS_CHECKIN_QUEUE;
    }
}

它更小,但不像@Alexander_Pogrebnyak的解决方案那样自动。如果枚举发生更改,则必须更新开关。

ServerTask.values()
:)上循环时,您只需要一个If,是否检查枚举的名称(例如,
HOOK\u BEFORE\u ALL\u TASKS
)或该参数的值(
“Execute”
)?如果它是一个参数,那么如果你为它输入getter的代码或者名称(如果它不是
private
Maps),那么它会很有帮助。uniqueIndex()
会让它不那么冗长。你可以添加一些注释来说明发生了什么on@jeremy. 什么是不清楚的?如果你问我,我会回答。不是DV,但我想到的一个原因是,你只是代码转储,你没有解释这些代码是如何工作的。通过Jeremy征求意见来说明正在发生的事情,我认为很明显,他不仅仅是在寻找解决方案,他实际上是想了解你为什么要这样做,以及它是如何工作的。ServerTask.valueOf(…)就是你要找的。如果枚举都是大写的,那么还可以使用ServerTask.valueOf(input.toUpperCase())@Jamie,在他的例子中,
enum
实例标识符和它们的
String
值不匹配(不仅仅是按大小写)。例如,
HOOK\u BEFORE\u所有任务
字符串
值为
“EXECUTE”
static ServerTask getServerTask(String name)
{
    switch(name)
    {
         case "Execute": return HOOK_BEFORE_ALL_TASKS;
         case "Copy master db": return COPY_MASTER_AND_SNAPSHOT_TO_HISTORY;
         case "Process Check-In Queue": return PROCESS_CHECKIN_QUEUE;
    }
}