Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert from String to a Java enum with large amount of values [duplicate]

Tags:

java

enums

Let's say I have an enum with 100 values. For simplicity's sake, take the following example:

public enum code {     CODE_1("string1"),     CODE_2("string2"),     CODE_3("string3"),     CODE_4("string4"),     ... } 

I want to create a public method to convert strings with a known format (like "string1", "string2"...) to the appropiate enum value CODE_1, CODE_2... Typically this is done by iterating over all values, and if a match is found, return that enum value. (Details can be found in this question.)

However, I'm concerned with reguraly looping over all values. Could this potentially be a huge bottleneck? What if instead of 100 element, there were 1000?

As an exercise for myself, I tried to optimize this lookup with a static map, which can assure O(1) lookup time given any string. I like this extra gimmick, but I only want to include it in my code if it is actually necessary. What are your thoughts and findings on using the iterating method vs the map method?

public enum Code {     ...     //enum values     ...       //The string-to-Code map     private static final Map<String,Code> CODE_MAP = populateMap();      private static Map<String,Code> populateMap()     {         Map<String,Code> map = new HashMap<String,Code>();          for(Code c : Code.values())         {             map.put(c.getCode(), c);         }          return map;     }       private String code;      private Code(String code)     {         this.code = code;     }      public String getCode()     {         return this.code;     }      public Code convertFromString(String code)     {         //assume that the given string is actually a key value in the map          return (Code) CODE_MAP.get(code);     } } 
like image 783
user1884155 Avatar asked Dec 30 '14 09:12

user1884155


People also ask

How to convert a string to an enum in Java?

How to convert a String to an enum in Java? How to convert a String to an enum in Java? The valueOf () method of the Enum class in java accepts a String value and returns an enum constant of the specified type.

What is the use of valueOf () method in enum in Java?

The valueOf () method of the Enum class in java accepts a String value and returns an enum constant of the specified type. Let us create an enum with name Vehicles with 5 constants representing models of 5 different scoters with their prices as values, as shown below −

How to iterate over enums in Java?

To iterate over enum list, use values () method on enum type which return all enum constants in an array. 3. Java enum to String To get single enum value (e.g. get prod URL from enum constant) use it’s value method, you created.

How do I get the value of an enum constant?

Getting Enum Value To get a single enum value (e.g., get production URL from enum constant), use the value method that we created. 4. Getting Enum by Name If we want to get enum constant using its name, then we should use valueOf () method.


2 Answers

You want a Map<String, Code>, but how to populate it neatly? Enums don't allow you to initialize a static fields before the enum instances are initialized, but there's a neat little trick, called the Initialization-on-demand holder idiom, that makes using a statically initialized map needed for this functionality easy to implement:

public enum Code {     CODE_1("string1"),     CODE_2("string2"),     CODE_3("string3"),     // etc     ;      private static class Holder {         static Map<String, Code> CODE_MAP = new HashMap<>();     }      private final String code;      private Code(String code) {         this.code = code;         Holder.CODE_MAP.put(code, this);     }      public String getCode() {         return this.code;     }      public Code convertFromString(String code) {         return Holder.CODE_MAP.get(code);     } } 

This works because the class loader initializes inner static classes before initializing the enum class, so the map is assigned ready to load during enum instance initialization.

No loops. No special code to load the map (done in constructor). Minimal code.

like image 123
Bohemian Avatar answered Oct 17 '22 02:10

Bohemian


Map is good option : cleaner code and O(1) . If you use for-loop then the best you get is O(n)

like image 42
sol4me Avatar answered Oct 17 '22 01:10

sol4me