J'ai la enum
comme:
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;
}
}
Je dois obtenir les noms Enum (PASSED
, AVERAGE
, GOOD
) en utilisant uniquement les identifiants (40,60, 80). Comment fait-on ça?
Créez une méthode statique dans votre enum
qui effectue une recherche dans values
(méthode implicite/membre, vous ne savez pas exactement de quoi il s'agit) et renvoie la valeur correspondante. Dans les cas où la méthode ne peut pas trouver de valeur correspondante, vous devez créer une entrée spéciale, par exemple. UNKNOWN
, que vous pouvez retourner. De cette façon, vous n’avez pas à retourner null
, ce qui est toujours une mauvaise idée.
public static EnumStatus getById(Long id) {
for(EnumStatus e : values()) {
if(e.id.equals(id)) return e;
}
return UNKNOWN;
}
Btw - votre code semble être faux. Le crochet après GOOD
semble ne pas y appartenir.
Cela peut être fait en utilisant une carte statique avec un initialiseur statique:
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;
}
}
Cela donnera une méthode O(1)
getById()
et détectera automatiquement si vous avez accidentellement des identifiants en double dans l'énumération.
Vous faites ce travail comme suit:
public static String fromId(long id) {
for (EnumStatus es : EnumStatus.values()) {
if (es.id.equals(id)) {
return es.getName();
}
}
throw new IllegalArgumentException();
}
Ajoutez une méthode dans votre Enum
et obtenez-la en passant des identifiants.
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;
}
public static EnumStatus getById(long id)
{
for (EnumStatus e : EnumStatus.values())
{
if (id == e.getId()) return e;
}
throw new IllegalArgumentException("oh no");
}
Parfois, l'ordinal de l'énum a une relation claire avec ce type d'identifiant, ce qui permet d'obtenir un moyen astucieux d'obtenir O(1) dans ces méthodes. Dans votre code, il est clair que
EnumStatus.X = 40 + 20 * ordinal
,
afin que vous puissiez exploiter le tableau statique généré sous les hottes .
public static EnumStatus fromId(Long id) {
int index = (id - 40L) / 20L;
return values()[index];
}
Itérer sur toutes les valeurs et comparer l'identifiant
for (EnumStatus enumStatus : EnumStatus.values()) {
if (..) {..}
}
Définir contrat
/**
* Contract that will allow Types with id to have generic implementation.
*/
public interface IdentifierType<T> {
T getId();
}
Appliquer le contrat
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;
}
}