2013-03-13 12 views
20

mam enum jak:Jak odzyskać nazwę Enum za pomocą id?

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

muszę uzyskać nazwy ENUM (PASSED, AVERAGE, GOOD) przy użyciu tylko identyfikatory (40,60, 80). Jak mam to zrobić?

Odpowiedz

39

Utwórz metodę statyczną w swoim enum, która wyszukuje w values (niejawna metoda/element, nie wiem dokładnie, która to jest) i zwraca odpowiednią wartość. W przypadkach, w których metoda nie może znaleźć pasującej wartości, należy utworzyć specjalną pozycję, np. UNKNOWN, którą możesz zwrócić. W ten sposób nie musisz zwracać null, co zawsze jest złym pomysłem.

public static EnumStatus getById(Long id) { 
    for(EnumStatus e : values()) { 
     if(e.id.equals(id)) return e; 
    } 
    return UNKNOWN; 
} 

Btw - Twój kod wydaje się być nieprawidłowy. Wspornik po GOOD wydaje się nie pasować.

+5

IMHO, nie powinieneś zwracać null w tego rodzaju metodach Enuma. Wyjątek RuntimeException (np. IllegalArgumentException) byłby lepszy. – jalopaba

+0

Myślę, że masz rację, "null" jest dość brzydki. Jestem także fanem fałszywych wartości, aby enum zawierało dodatkową wartość 'UNKNOWN' z wartościami, które nie pasują do niczego. Oczywiście zależy to od twojego środowiska. – Joshua

8

Można to zrobić za pomocą statycznego mapę wraz ze statycznym inicjatora:

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

} 

To dadzą O(1)getById() metody i automatycznie wykryć, jeśli przypadkowo mają zduplikowane identyfikatory w enum.

+0

Podoba mi się twój pomysł z używaniem mapy dla stałych czasów dostępu. Dla dużych wyrażeń na pewno dobrze. Sprawdzanie wartości zwrotnej put jest naprawdę fajne. – Joshua

+0

Jeśli chodzi o O (1) dla tego rodzaju metod, jeśli taki id i wewnętrzny porządek porządkowy są powiązane równaniem, możesz wykorzystać wygenerowaną statyczną tablicę do uzyskania O (1) (zobacz moją odpowiedź). – jalopaba

+0

@NPE Bardzo podoba mi się pomysł statycznej mapy i sprawdzanie niezmienności, że każda stała ma unikalny identyfikator. Dzięki. + 1. – Geek

0

iteracyjne nad wszystkie wartości i porównać Id

for (EnumStatus enumStatus : EnumStatus.values()) { 
    if (..) {..} 
} 
1

Dodaj metodę w swojej Enum i dostać go przekazując identyfikatory.

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

dokonać tej pracy w następujący sposób:

public static String fromId(long id) { 
     for (EnumStatus es : EnumStatus.values()) { 
      if (es.id.equals(id)) { 
       return es.getName(); 
      } 
     } 
     throw new IllegalArgumentException(); 
} 
1
public static EnumStatus getById(long id) 
{ 
    for (EnumStatus e : EnumStatus.values()) 
    { 
    if (id == e.getId()) return e; 
    } 
    throw new IllegalArgumentException("oh no"); 
} 
0

Czasami porządkowa wyliczenia zawiera wyraźny związek z tego rodzaju identyfikatorów, umożliwiając zgrabny sposób, aby uzyskać O (1) w tych metody. W kodzie, jest oczywiste, że

EnumStatus.X = 40 + 20 * ordinal,

, dzięki czemu można wykorzystać static array that is generated under the hoods.

public static EnumStatus fromId(Long id) { 
    int index = (id - 40L)/20L; 
    return values()[index]; 
} 
+1

Myślę, że powinno to przynajmniej potwierdzić, że założenie jest prawidłowe. W przeciwnym razie może to łatwo prowadzić do kruchego kodu. – NPE

0

Definiowanie zamówienia

/** 
* Contract that will allow Types with id to have generic implementation. 
*/ 
public interface IdentifierType<T> { 
    T getId(); 
} 

Zastosuj zamówieniu na

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

Helper/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; 
    } 
} 
Powiązane problemy