2011-07-14 11 views
64

Mam enum w Javie:Jak uzyskać wartość Enum z indeksu w Javie?

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

Chcę uzyskać dostęp do wartości enum przez indeks, na przykład

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

Jak mam to zrobić?

+7

W informatyce indeksy zaczynają się od 0, nie 1 ;-) – fredoverflow

+1

Czy na pewno chcesz? Generalnie nie powinieneś dotykać porządków porządkowych, poza implementowaniem struktur danych niskiego poziomu (a następnie użyć mechanizmów alternatywnych, takich jak nazwa, do utrwalania). –

+0

Można również użyć stałych w klasie java.util.Calendar. Są one ponumerowane od 0 do 11 w okresie od stycznia do grudnia. Uważajcie na 12, ponieważ jest to czas nieokreślony (coś, co ma związek z kalendarzem księżycowym). Ale jestem ciekawy, dlaczego ponownie wymyśliłem koło stałych stałych, które już są "dostępne" w JRE? –

Odpowiedz

162

Spróbuj

Months.values()[index] 
+26

Należy zauważyć, że za każdym razem klonuje kopię tablicy wartości, więc jeśli wywołujesz ją w wewnętrznej pętli kodu wrażliwego na wydajność, możesz wykonać kopię statyczną i użyć jej. –

+0

Jestem zdezorientowany, więc dlaczego nie miałbym zamiast tego używać tablicy? –

+0

@AudeudeSamaiya może chcieć używać właściwych stałych wyliczeniowych (Months.JAN) w kodzie zamiast miesięcy [1] wszędzie. –

7

spróbuje użyć EnumMap lub EnumSet?

+0

+1 ode mnie. Rozwiązuje prawdopodobny problem, zamiast wysyłać OP w niewłaściwym kierunku. –

+2

Czy możesz wyjaśnić, w jaki sposób rozwiązuje problem pobierania wartości typu wyliczenia przy użyciu indeksu (integer) jako argument? EnumMap wymaga, aby klucz był typu enum. –

+1

Zgadza się. To wcale nie odpowiada na pytanie. –

17

Oto trzy sposoby, aby to zrobić.

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

} 
+3

'public static' zmienne (zarówno tablicowe, jak i nie-końcowe). Euw. A wyjątek 'IllegalArgumentException' miałby o wiele więcej sensu niż zwrócenie bomby' null'. –

+0

tak. nigdy nie powiedziałem, że zrobię to w ten sposób. –

1

prostu próbowałem to samo i wymyślił następujące rozwiązanie:

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

klasa ma swoje własne wartości zapisane wewnątrz tablicy i używam tablicę, aby uzyskać enum w indexposition. Jak wspomniano powyżej tablic zacząć liczyć od 0, jeśli chcesz, aby indeks zacząć od „1” po prostu zmienić te dwie metody:

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

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

Wewnątrz mój główny uzyskać potrzebne kraje-Object z

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

, która ustawia currCountry na ostatni kraj, w tym przypadku Countries.KENTUCKY.

Pamiętaj tylko, że kod ten ma duży wpływ na ArrayOutOfBoundsExceptions, jeśli używasz zakodowanych znaków, aby uzyskać swoje obiekty.

Powiązane problemy