Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

get enum name from enum value [duplicate]

Tags:

java

enums

I've read a lot about how obtain the corresponding name of an enum from its value using java, but no example seems to work for me! What is wrong?

public class Extensions {


    public enum RelationActiveEnum
    {
        Invited(0),
        Active(1),
        Suspended(2);

        private final int value;

        private RelationActiveEnum(final int value) {
            this.value = value;
        }
    }

}

and in another class I use:

        int dbValue = supp.ACTIVE;
        Extensions.RelationActiveEnum enumValue(dbValue);
        String stringName = enumValue.toString(); //Visible
        // OR
        int dbValuee = supp.ACTIVE;
        String stringValue = Enum.GetName(typeof(RelationActiveEnum), dbValue);

I should work, right? but it doesn't!!!! it tells me that dbValue cannote be cast to RelationActiveEnum...

like image 539
Camilla Avatar asked Jan 14 '13 13:01

Camilla


People also ask

Can enum have duplicate values?

Two enum names can have same value. For example, in the following C program both 'Failed' and 'Freezed' have same value 0.

Can enum have two same values python?

By definition, the enumeration member values are unique. However, you can create different member names with the same values.

How do you find the value of an enum?

To get the value of enum we can simply typecast it to its type. In the first example, the default type is int so we have to typecast it to int. Also, we can get the string value of that enum by using the ToString() method as below.


7 Answers

Say we have:

public enum MyEnum {
  Test1, Test2, Test3
}

To get the name of a enum variable use name():

MyEnum e = MyEnum.Test1;
String name = e.name(); // Returns "Test1"

To get the enum from a (string) name, use valueOf():

String name = "Test1";
MyEnum e = Enum.valueOf(MyEnum.class, name);

If you require integer values to match enum fields, extend the enum class:

public enum MyEnum {
  Test1(1), Test2(2), Test3(3);

  public final int value;

  MyEnum(final int value) {
     this.value = value;
  }
}

Now you can use:

MyEnum e = MyEnum.Test1;
int value = e.value; // = 1

And lookup the enum using the integer value:

MyEnum getValue(int value) {
  for(MyEnum e: MyEnum.values()) {
    if(e.value == value) {
      return e;
    }
  }
  return null;// not found
}
like image 174
Veger Avatar answered Oct 17 '22 07:10

Veger


Since your 'value' also happens to match with ordinals you could just do:

public enum RelationActiveEnum {
    Invited,
    Active,
    Suspended;

    private final int value;

    private RelationActiveEnum() {
        this.value = ordinal();
    }
}

And getting a enum from the value:

int value = 1;
RelationActiveEnum enumInstance = RelationActiveEnum.values()[value];

I guess an static method would be a good place to put this:

public enum RelationActiveEnum {
     public static RelationActiveEnum fromValue(int value) 
             throws IllegalArgumentException {
         try {
              return RelationActiveEnum.values()[value]
         } catch(ArrayIndexOutOfBoundsException e) {
              throw new IllegalArgumentException("Unknown enum value :"+ value);
         }
     }
}   

Obviously this all falls apart if your 'value' isn't the same value as the enum ordinal.

like image 20
Gareth Davis Avatar answered Oct 17 '22 09:10

Gareth Davis


You could create a lookup method. Not the most efficient (depending on the enum's size) but it works.

public static String getNameByCode(int code){
  for(RelationActiveEnum e : RelationActiveEnum.values()){
    if(code == e.value) return e.name();
  }
  return null;
}

And call it like this:

RelationActiveEnum.getNameByCode(3);
like image 32
lcguida Avatar answered Oct 17 '22 09:10

lcguida


What you can do is

RelationActiveEnum ae = Enum.valueOf(RelationActiveEnum.class,
                                     RelationActiveEnum.ACTIVE.name();

or

RelationActiveEnum ae = RelationActiveEnum.valueOf(
                                     RelationActiveEnum.ACTIVE.name();

or

// not recommended as the ordinal might not match the value
RelationActiveEnum ae = RelationActiveEnum.values()[
                                     RelationActiveEnum.ACTIVE.value];

By if you want to lookup by a field of an enum you need to construct a collection such as a List, an array or a Map.

public enum RelationActiveEnum {
    Invited(0),
    Active(1),
    Suspended(2);

    private final int code;

    private RelationActiveEnum(final int code) {
        this.code = code;
    }

    private static final Map<Integer, RelationActiveEnum> BY_CODE_MAP = new LinkedHashMap<>();
    static {
        for (RelationActiveEnum rae : RelationActiveEnum.values()) {
            BY_CODE_MAP.put(rae.code, rae);
        }
    }

    public static RelationActiveEnum forCode(int code) {
        return BY_CODE_MAP.get(code);
    }
}

allows you to write

String name = RelationActiveEnum.forCode(RelationActiveEnum.ACTIVE.code).name();
like image 36
Peter Lawrey Avatar answered Oct 17 '22 09:10

Peter Lawrey


In my case value was not an integer but a String. getNameByCode method can be added to the enum to get name of a String value-

enum CODE {
    SUCCESS("SCS"), DELETE("DEL");

    private String status;

    /**
     * @return the status
     */
    public String getStatus() {
        return status;
    }

    /**
     * @param status
     *            the status to set
     */
    public void setStatus(String status) {
        this.status = status;
    }

    private CODE(String status) {
        this.status = status;
    }

    public static String getNameByCode(String code) {
        for (int i = 0; i < CODE.values().length; i++) {
            if (code.equals(CODE.values()[i].status))
                return CODE.values()[i].name();
        }
        return null;
    }
like image 38
Mithun Khatri Avatar answered Oct 17 '22 09:10

Mithun Khatri


If you want something more efficient in runtime condition, you can have a map that contains every possible choice of the enum by their value. But it'll be juste slower at initialisation of the JVM.

import java.util.HashMap;
import java.util.Map;

/**
 * Example of enum with a getter that need a value in parameter, and that return the Choice/Instance 
 * of the enum which has the same value.
 * The value of each choice can be random.
 */
public enum MyEnum {
    /** a random choice */
    Choice1(4),
    /** a nother one */
    Choice2(2),
    /** another one again */
    Choice3(9);
    /** a map that contains every choices of the enum ordered by their value. */
    private static final Map<Integer, MyEnum> MY_MAP = new HashMap<Integer, MyEnum>();
    static {
        // populating the map
        for (MyEnum myEnum : values()) {
            MY_MAP.put(myEnum.getValue(), myEnum);
        }
    }
    /** the value of the choice */
    private int value;

    /**
     * constructor
     * @param value the value
     */
    private MyEnum(int value) {
        this.value = value;
    }

    /**
     * getter of the value
     * @return int
     */
    public int getValue() {
        return value;
    }

    /**
     * Return one of the choice of the enum by its value.
     * May return null if there is no choice for this value.
     * @param value value
     * @return MyEnum
     */
    public static MyEnum getByValue(int value) {
        return MY_MAP.get(value);
    }

    /**
     * {@inheritDoc}
     * @see java.lang.Enum#toString()
     */
    public String toString() {
        return name() + "=" + value;
    }

    /**
     * Exemple of how to use this class.
     * @param args args
     */
    public static void main(String[] args) {
        MyEnum enum1 = MyEnum.Choice1;
        System.out.println("enum1==>" + String.valueOf(enum1));
        MyEnum enum2GotByValue = MyEnum.getByValue(enum1.getValue());
        System.out.println("enum2GotByValue==>" + String.valueOf(enum2GotByValue));
        MyEnum enum3Unknown = MyEnum.getByValue(4);
        System.out.println("enum3Unknown==>" + String.valueOf(enum3Unknown));
    }
}
like image 42
user3328716 Avatar answered Oct 17 '22 09:10

user3328716


This is my take on it:

public enum LoginState { 
    LOGGED_IN(1), LOGGED_OUT(0), IN_TRANSACTION(-1);

    private int code;

    LoginState(int code) {
        this.code = code;
    }

    public int getCode() {
        return code;
    }

    public static LoginState getLoginStateFromCode(int code){
        for(LoginState e : LoginState.values()){
            if(code == e.code) return e;
        }
        return LoginState.LOGGED_OUT; //or null
    }
};

And I have used it with System Preferences in Android like so:

LoginState getLoginState(int i) {
    return LoginState.getLoginStateFromCode(
                prefs().getInt(SPK_IS_LOGIN, LoginState.LOGGED_OUT.getCode())
            );
}

public static void setLoginState(LoginState newLoginState) {
    editor().putInt(SPK_IS_LOGIN, newLoginState.getCode());
    editor().commit();
}

where pref and editor are SharedPreferences and a SharedPreferences.Editor

like image 41
msysmilu Avatar answered Oct 17 '22 07:10

msysmilu