Java enum string matching

I have an enum like this:

public enum ServerTask {

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

      

I also have a string (say string = "Execute") that I would like to render into an instance of the ServerTask enumeration, based on which string in the enumeration it matches. Is there a better way to do this than doing equality checks between the string I want to match and each element in the enum? it looks like it would be a lot of it if there were statements as my enum was quite large

+3


source to share


4 answers


At some level, you will have to iterate over the entire set of enums that you have, and you will have to compare them to equals - either through a mapping structure (initial collection) or through a rudimentary loop.

It's fairly easy to accomplish with a rudimentary loop, so I see no reason why you don't want to go that route. The code snippet below assumes the field has a name friendlyTask

.

public static ServerTask forTaskName(String friendlyTask) {
    for (ServerTask serverTask : ServerTask.values()) {
        if(serverTask.friendlyTask.equals(friendlyTask)) {
            return serverTask;
        }
    }
    return null;
}

      



The caveat to this approach is that the data will not be stored internally, and depending on how many enumerations you actually have and how many times you want to call this method, it will be slightly worse than initialization with a map.

However, this approach is the simplest. If you find yourself in a position where you have several hundred censuses (even more than 20 is a smell to me), think about what exactly those enumerations are listing and what you need to do to break it down a little more.

+5


source


Create a static reverse lookup map.



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

}

      

+1


source


If you need to get enum

from String

often , then creating a reverse map like Alexander might be worth it.

If you only need to do this once or twice , iterating over the values ​​with a single if statement might be a better choice (e.g. Nizil's comment hints)

for (ServerTask task : ServerTask.values())
{
    //Check here if strings match
}

      

However, there is a way not to iterate over the values ​​at all. If you can make sure that the instance name enum

and its value are String

identical, you can use:

ServerTask.valueOf("EXECUTE")

      

which will give you ServerTask.EXECUTE.

Please refer to this for more information.

Having said that, I would not recommend this approach unless you agree that the instances have the same String representations, since their IDs are and are your performance critical application that more often than not .

+1


source


You can write a method like this:

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

      

It's smaller but not automatic like @Alexander_Pogrebnyak's solution. If the listing changes, you will need to upgrade the switch.

0


source







All Articles