Monday, August 29, 2016

Reverse Lookup of Java Enum Values

I defined an enum with a structure similar to the following code:

public enum EnumWithIntValue {  
     ZERO(0),  
     ONE(1),  
     TWO(2),  
     THREE(3),  
     FOUR(4),  
     FIVE(5);

     private final int intValue;

     private EnumWithIntValue(final int intValue) {  
          this.intValue = intValue;  
     }

     public final int getValue() {  
          return this.intValue;  
     }  
}  

I then wanted to do a reverse lookup where I pass in a primitive int value and return the corresponding enum value. This was readily accomplished by adding the following static method to EnumWithIntValue:

public static final EnumWithIntValue valueOf(final int intValueParam) {
     for (EnumWithIntValue intValueEnum : values()) {
          if (intValueEnum.intValue == intValueParam) {
               return intValueEnum;
          }
     }

     throw new IllegalArgumentException("Invalid int value parameter " + intValueParam);
}

Hold up. What on Earth does values() do? If you look at the java.lang.Enum code from the JDK it does not exist. But according to the Enum Types section of the Java Tutorials:

The compiler automatically adds some special methods when it creates an enum. For example, they have a static values method that returns an array containing all of the values of the enum in the order they are declared. This method is commonly used in combination with the for-each construct to iterate over the values of an enum type.

Ok all of that makes sense (sort of). However, what does values() do every time it is called? Or to put it another way, is values() giving me a reference to the same array each time it is called or is it cloning the encapsulated array and giving me a copy each time? Let's find out:

public static void main(final String[] args) {
     EnumWithIntValue[] array = values();

     System.out.println(array);

     array = values();

     System.out.println(array);
}

Well lookie here:

[Labc.test.EnumWithIntValue;@322ba3e4
[Labc.test.EnumWithIntValue;@4f14e777

Great, so each call to values() is obviously cloning the encapsulated array which is no good from a performance perspective. Of course the JDK is more worried about giving away the internal array reference which can lead to the possibility of someone altering said array which is also a big no-no. But for the purpose of my valueOf() method, that array is only used within my enum.

Therefore, let's cache the array inside the enum declaration and then update the valueOf() method to use the cached instance instead:

     // Declare the enum cache as a private constant
     private static final EnumWithIntValue[] enumValueArray = EnumWithIntValue.values();

     // Then update the values() call inside valueOf() to reference the enum cache instead
     for (EnumWithIntValue intValueEnum : enumValueArray) {
          ...
     }

And voila! A reverse enum lookup that performs as well as it looks!

16 comments:

  1. I have read your blog its very attractive and impressive. I like it your blog.

    Java Training in Chennai Core Java Training in Chennai Core Java Training in Chennai

    Java Online Training Java Online Training Core Java 8 Training in Chennai Core java 8 online training JavaEE Training in Chennai Java EE Training in Chennai

    ReplyDelete
  2. The blog gave me idea to reverse java enum values Thanks for sharing it
    Hadoop Training in Chennai

    ReplyDelete
  3. After reading this blog I am very strong in this topics and this blog is really helpful to all.. Explanation are very clear so it is easy to understand.. Thanks for sharing this blog…
    Big Data Analytics Training in Chennai | Web Designing Training in Chennai

    ReplyDelete
  4. This is an awesome post.Really very informative and creative contents. These concept is a good way to enhance the knowledge.
    I like it and help me to development very well.Thank you for this brief explanation and very nice information.Well, got a good knowledge.
    Java training in Indira nagar
    Java training in Rajaji nagar
    Java training in Marathahalli
    Java training in Btm layout
    Java training in Marathahalli

    ReplyDelete
  5. You have provided a nice article, Thank you very much for this one. And I hope this will be useful for many people. And I am waiting for your next post keep on updating these kinds of knowledgeable things
    Java Training in Chennai
    Java Training in Coimbatore
    Java Training in Bangalore

    ReplyDelete
  6. I have been reading for the past two days about your blogs and topics, still on fetching! Wondering about your words on each line was massively effective. Techno-based information has been fetched in each of your topics. Sure it will enhance and fill the queries of the public needs. Feeling so glad about your article. Thanks…!
    best software testing training in chennai
    best software testing training institute in chennai with placement
    software testing training
    courses

    software testing training and placement
    software testing training online
    software testing class
    software testing classes in chennai
    best software testing courses in chennai
    automation testing courses in chennai

    ReplyDelete