web-dev-qa-db-fra.com

Comment obtenir Enum Value depuis index en Java?

J'ai un enum en Java:

public enum Months
{
    JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC
}

Je souhaite accéder aux valeurs enum par index, par exemple.

Months(1) = JAN;
Months(2) = FEB;
...

Comment vais-je faire ça?

88
jk_

Essaye ça

Months.values()[index]
202
Harry Joy

Voici trois façons de le faire.

public enum Months {
    JAN(1), FEB(2), MAR(3), APR(4), MAY(5), JUN(6), JUL(7), AUG(8), SEP(9), OCT(10), NOV(11), DEC(12);


    int monthOrdinal = 0;

    Months(int ord) {
        this.monthOrdinal = ord;
    }

    public static Months byOrdinal2ndWay(int ord) {
        return Months.values()[ord-1]; // less safe
    }

    public static Months byOrdinal(int ord) {
        for (Months m : Months.values()) {
            if (m.monthOrdinal == ord) {
                return m;
            }
        }
        return null;
    }
    public static Months[] MONTHS_INDEXED = new Months[] { null, JAN, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC };

}




import static junit.framework.Assert.assertEquals;

import org.junit.Test;

public class MonthsTest {

@Test
public void test_indexed_access() {
    assertEquals(Months.MONTHS_INDEXED[1], Months.JAN);
    assertEquals(Months.MONTHS_INDEXED[2], Months.FEB);

    assertEquals(Months.byOrdinal(1), Months.JAN);
    assertEquals(Months.byOrdinal(2), Months.FEB);


    assertEquals(Months.byOrdinal2ndWay(1), Months.JAN);
    assertEquals(Months.byOrdinal2ndWay(2), Months.FEB);
}

}
20
Trever Shick

Essayez d'utiliser EnumMap ou EnumSet ?

8
Sergii Zagriichuk

J'ai juste essayé la même chose et suis venu avec la solution suivante:

public enum Countries {
    TEXAS,
    FLORIDA,
    OKLAHOMA,
    KENTUCKY;

    private static Countries[] list = Countries.values();

    public static Countries getCountry(int i) {
        return list[i];
    }

    public static int listGetLastIndex() {
        return list.length - 1;
    }
}

La classe a ses propres valeurs enregistrées dans un tableau et j'utilise ce tableau pour obtenir l'énumération à l'indexposition. Comme mentionné ci-dessus, les tableaux commencent à compter à partir de 0, si vous voulez que votre index commence à '1', remplacez simplement ces deux méthodes par:

public static String getCountry(int i) {
    return list[(i - 1)];
}

public static int listGetLastIndex() {
    return list.length;
}

À l'intérieur de mon Main, j'obtiens le pays-objet nécessaire avec

public static void main(String[] args) {
   int i = Countries.listGetLastIndex();
   Countries currCountry = Countries.getCountry(i);
}

qui définit pays dans le dernier pays, en l’occurrence pays.KENTUCKY.

Rappelez-vous simplement que ce code est très affecté par les exceptions ArrayOutOfBoundsExceptions si vous utilisez des indicateurs codés en dur pour obtenir vos objets.

1
Blauspecht

J'ai récemment eu le même problème et utilisé la solution fournie par Harry Joy. Cette solution ne fonctionne qu'avec une énumération à base zéro cependant. Je ne le considérerais pas non plus sauf s'il ne traitait pas les index qui sont hors de portée.

La solution que j'ai finalement utilisée n'est peut-être pas si simple, mais c'est une sauvegarde complète qui ne nuira pas aux performances de votre code, même avec de gros enums:

public enum Example {

    UNKNOWN(0, "unknown"), ENUM1(1, "enum1"), ENUM2(2, "enum2"), ENUM3(3, "enum3");

    private static HashMap<Integer, Example> enumById = new HashMap<>();
    static {
        Arrays.stream(values()).forEach(e -> enumById.put(e.getId(), e));
    }

    public static Example getById(int id) {
        return enumById.getOrDefault(id, UNKNOWN);
    }

    private int id;
    private String description;

    private Example(int id, String description) {
        this.id = id;
        this.description= description;
    }

    public String getDescription() {
        return description;
    }

    public int getId() {
        return id;
    }
}

Si vous êtes sûr de ne jamais être hors de portée avec votre index et que vous ne voulez pas utiliser UNKNOWN comme je l'ai fait ci-dessus, vous pouvez bien sûr aussi faire:

public static Example getById(int id) {
        return enumById.get(id);
}
0
Mirko Brandt