Как получить имя Enum с помощью идентификатора?
У меня есть enum
как:
public enum EnumStatus {
PASSED(40L, "Has Passed"),
AVERAGE(60L, "Has Average Marks"),
GOOD(80L, "Has Good Marks");
private java.lang.String name;
private java.lang.Long id;
EnumStatus(Long id, java.lang.String name) {
this.name = name;
this.id = id;
}
public java.lang.String getName() {
return name;
}
public java.lang.Long getId() {
return id;
}
}
Мне нужно получить имена Enum (PASSED
, AVERAGE
, GOOD
), используя только идентификаторы (40,60, 80). Как это сделать?
Ответы
Ответ 1
Создайте статический метод в enum
, который ищет в values
(неявный метод/член, не знает точно, что это такое) и возвращает соответствующее значение. Для случаев, когда метод не может найти подходящее значение, вы должны создать специальную запись, например. UNKNOWN
, который вы можете вернуть. Таким образом, вам не нужно возвращать null
, что всегда плохой идеей.
public static EnumStatus getById(Long id) {
for(EnumStatus e : values()) {
if(e.id.equals(id)) return e;
}
return UNKNOWN;
}
Btw - ваш код кажется неправильным. Скобка после GOOD
, похоже, не принадлежит.
Ответ 2
Это можно сделать, используя статическую карту вместе со статическим инициализатором:
public enum EnumStatus {
PASSED(40L, "Has Passed"),
AVERAGE(60L, "Has Average Marks"),
GOOD(80L, "Has Good Marks");
private static final Map<Long, EnumStatus> byId = new HashMap<Long, EnumStatus>();
static {
for (EnumStatus e : EnumStatus.values()) {
if (byId.put(e.getId(), e) != null) {
throw new IllegalArgumentException("duplicate id: " + e.getId());
}
}
}
public static EnumStatus getById(Long id) {
return byId.get(id);
}
// original code follows
private java.lang.String name;
private java.lang.Long id;
EnumStatus(Long id, java.lang.String name) {
this.name = name;
this.id = id;
}
public java.lang.String getName() {
return name;
}
public java.lang.Long getId() {
return id;
}
}
Это даст метод O(1)
getById()
и автоматически обнаружит, если у вас случайно есть дубликаты идентификаторов в перечислении.
Ответ 3
Вы делаете эту работу следующим образом:
public static String fromId(long id) {
for (EnumStatus es : EnumStatus.values()) {
if (es.id.equals(id)) {
return es.getName();
}
}
throw new IllegalArgumentException();
}
Ответ 4
Добавьте метод в свой Enum
и получите его, передав идентификаторы.
public static ArrayList<EnumStatus> getEnumStatusById(ArrayList<Long> idList) {
ArrayList<EnumStatus> listById = new ArrayList();
for(EnumStatus es: EnumStatus.values()) {
if( idList.contains(es.getId())) {
listById.add(es);
}
}
return listById;
}
Ответ 5
public static EnumStatus getById(long id)
{
for (EnumStatus e : EnumStatus.values())
{
if (id == e.getId()) return e;
}
throw new IllegalArgumentException("oh no");
}
Ответ 6
Итерация по всем значениям и сравнение Id
for (EnumStatus enumStatus : EnumStatus.values()) {
if (..) {..}
}
Ответ 7
Иногда порядковый номер enum имеет четкую связь с этим типом идентификаторов, позволяя аккуратный способ получить O (1) в этих методах. В вашем коде ясно, что
EnumStatus.X = 40 + 20 * ordinal
,
чтобы вы могли использовать статический массив который создается под капотами.
public static EnumStatus fromId(Long id) {
int index = (id - 40L) / 20L;
return values()[index];
}
Ответ 8
Определить контракт
/**
* Contract that will allow Types with id to have generic implementation.
*/
public interface IdentifierType<T> {
T getId();
}
Применить контракт
public enum EntityType implements IdentifierType<Integer> {
ENTITY1(1, "ONE), ENTITY2(2, "TWO");
private Integer id;
private String name;
private EntityType(int id, String name) {
this.id = id;
this.name = name;
}
public static EntityType valueOf(Integer id) {
return EnumHelper.INSTANCE.valueOf(id, EntityType.values());
}
@Override
public Integer getId() {
return id;
}
}
Помощник /Util
public enum EnumHelper {
INSTANCE;
/**
* This will return {@link Enum} constant out of provided {@link Enum} values with the specified id.
* @param id the id of the constant to return.
* @param values the {@link Enum} constants of specified type.
* @return the {@link Enum} constant.
*/
public <T extends IdentifierType<S>, S> T valueOf(S id, T[] values) {
if (!values[0].getClass().isEnum()) {
throw new IllegalArgumentException("Values provided to scan is not an Enum");
}
T type = null;
for (int i = 0; i < values.length && type == null; i++) {
if (values[i].getId().equals(id)) {
type = values[i];
}
}
return type;
}
}
Ответ 9
Если вы хотите сделать это для большего количества перечислений, я использую это:
public static T FindEnum<T>(long id) where T : struct
{
return (T)Enum.ToObject(typeof(T), id);
}