【问题标题】:get enum name from enum value [duplicate]从枚举值中获取枚举名称[重复]
【发布时间】:2012-12-28 11:01:31
【问题描述】:

我已经阅读了很多关于如何使用 java 从其值中获取 enum 的相应名称的信息,但似乎没有一个示例对我有用!怎么了?

public class Extensions {


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

        private final int value;

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

}

在我使用的另一个类中:

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

我应该工作,对吧?但它没有!!!!它告诉我 dbValue 不能转换为 RelationActiveEnum ...

【问题讨论】:

  • supp.ACTIVE 还是 supp.Active?
  • 请确认:您要获取给定int值的对应名称吗? IE。 1 --> ActiveActive --> 1?
  • 它是 supp.ACTIVE,我从数据库中获取的值,可以是 0,1 或 2... 是的,我在网络上搜索了 java 中的示例,我读到了类似此处发布的内容-

标签: java enums


【解决方案1】:

假设我们有:

public enum MyEnum {
  Test1, Test2, Test3
}

要获取枚举变量的名称,请使用name()

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

要从(字符串)名称中获取枚举,请使用valueOf()

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

如果您需要integer 值来匹配枚举字段,请扩展枚举类:

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

  public final int value;

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

现在你可以使用了:

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

并使用整数值查找枚举:

MyEnum getValue(int value) {
  for(MyEnum e: MyEunm.values()) {
    if(e.value == value) {
      return e;
    }
  }
  return null;// not found
}

【讨论】:

  • 我建议在未找到值的情况下抛出异常:InvalidArgumentException
【解决方案2】:

由于您的“价值”也恰好与序数匹配,您可以这样做:

public enum RelationActiveEnum {
    Invited,
    Active,
    Suspended;

    private final int value;

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

并从值中获取枚举:

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

我想一个静态方法会是一个很好的地方:

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

显然,如果您的“值”与枚举序数不同,这一切都会崩溃。

【讨论】:

  • 谢谢,非常简单,而且成功了!!非常感谢
  • 请注意差距...如果您的值不是序数...请查看@PeterLawrey的答案,并在您的枚举中将其设为静态方法,以防您改变主意: )
  • 鲍勃叔叔说使用序数是个坏主意。我同意这一点。
  • @Piotr 我怀疑 Uncle 指的是传递序数和/或持久化它,这是个好建议.. 使用名称或其他标识符。但是鉴于问题,这就是您解决问题的方法。
【解决方案3】:

您可以创建一个查找方法。不是最有效的(取决于枚举的大小),但它可以工作。

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

然后这样称呼它:

RelationActiveEnum.getNameByCode(3);

【讨论】:

  • 投赞成票,因为并非总是枚举中的位置RelationActiveEnum.values()[value] 表示它的值。
  • 这可能有性能问题,所以我推荐这个option
【解决方案4】:

你能做的是

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

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

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

如果你想通过枚举的某个字段进行查找,你需要构造一个集合,例如 List、数组或 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);
    }
}

允许你写

String name = RelationActiveEnum.forCode(RelationActiveEnum.ACTIVE.code).name();

【讨论】:

  • 出于好奇,您为什么使用LinkedHashMap 而不仅仅是HashMap
  • @mluisbrown 我倾向于使用 LinkedHashMap,因为它更容易调试。添加条目时,打印时它始终位于末尾。使用 HashMap esp 是一个大的 HashMap,你不知道它会去哪里。
【解决方案5】:

在我的例子中,值不是整数而是字符串。 getNameByCode 方法可以添加到枚举中以获取字符串值的名称-

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

【讨论】:

    【解决方案6】:

    如果您想要在运行时条件下更高效,您可以拥有一个映射,其中包含枚举的每个可能选择的值。但是在初始化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));
        }
    }
    

    【讨论】:

      【解决方案7】:

      这是我的看法:

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

      我已经将它与 Android 中的系统偏好设置一起使用,如下所示:

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

      其中prefeditorSharedPreferencesSharedPreferences.Editor

      【讨论】:

        猜你喜欢
        • 2016-12-07
        • 2018-04-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-08
        • 1970-01-01
        • 1970-01-01
        • 2012-08-11
        相关资源
        最近更新 更多