2013-03-13 14 views
20

Ho la enum come:Come recuperare il nome Enum utilizzando l'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; 
    } 
} 

devo ottenere i nomi Enum (PASSED, AVERAGE, GOOD) utilizzando solo gli ID (40,60, 80). Come lo faccio?

risposta

39

Creare un metodo statico nel proprio enum che ricerca in values (metodo implicito/membro, non so esattamente quale sia) e restituisce il valore corrispondente. Per i casi in cui il metodo non è in grado di trovare un valore corrispondente, è necessario creare una voce speciale, ad es. UNKNOWN, che è possibile restituire. In questo modo, non è necessario restituire null, che è sempre una cattiva idea.

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

Btw - il tuo codice sembra essere sbagliato. La parentesi dopo il GOOD sembra non appartenere a questo.

+5

IMHO, non dovresti restituire nulla in questo tipo di metodi di Enum. Una RuntimeException (ad esempio IllegalArgumentException) sarebbe meglio. – jalopaba

+0

Penso che tu abbia ragione, "null" è piuttosto brutto. Sono anche un fan dei valori dummy in modo che l'enumerazione contenga un valore aggiuntivo 'UNKNOWN' con valori che non corrispondono a nulla. Naturalmente questo dipende dal tuo ambiente. – Joshua

8

questo può essere fatto utilizzando una mappa statica con un inizializzatore statico:

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

} 

Questo vi darà un metodo O(1)getById(), e rileva automaticamente se avete accidentalmente ID duplicati nel enum.

+0

Mi piace l'idea con l'utilizzo della mappa per i tempi di accesso costante. Per le grandi enumerazioni sicuramente una buona cosa. Anche controllare il valore di ritorno di put è davvero interessante. – Joshua

+0

Per quanto riguarda O (1) per questo tipo di metodi, se tale id e l'ordinale interno sono correlati da un'equazione, è possibile sfruttare l'array statico generato per ottenere O (1) (vedere la mia risposta). – jalopaba

+0

@NPE Mi piace molto l'idea di una mappa statica e il controllo dell'invarianza che ogni costante abbia un ID univoco. Grazie. + 1. – Geek

0

iterare su tutti i valori e confrontare Id

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

Aggiungi un metodo nella Enum e farlo passando ids.

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

È fare questo lavoro nel modo seguente:

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

volte ordinale del enum ha una chiara relazione con questo tipo di ID, consentendo un modo pulito per ottenere O (1) in questi metodi. Nel codice, è chiaro che

EnumStatus.X = 40 + 20 * ordinal,

in modo da poter sfruttare la static array that is generated under the hoods.

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

Penso che questo dovrebbe almeno confermare che l'assunto sia corretto. Altrimenti, questo può facilmente portare a un codice fragile. – NPE

0

Definire contratto

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

Applicare contratto

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