2011-07-14 14 views
64

Java'da bir numaram var:Enum Value, Java'daki dizinden nasıl alınır?

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

Enum değerlerine endeksle erişmek istiyorum, ör.

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

Bunu nasıl yaparım?

+7

Bilgisayar bilimlerinde, endeksler 0'dan başlar, 0 değil; – fredoverflow

+1

İstediğinizden emin misiniz? Genel olarak, düşük seviyeli veri yapılarını uygulamaktan başka, sıraya dokunmamanız gerekir (ve sonra, sebat için isim gibi alternatif mekanizmalar kullanın). –

+0

Ayrıca java.util.Calendar sınıfındaki sabitleri de kullanabilirsiniz. Jan - Dec için 0 - 11 olarak numaralandırılıyorlar. UnDecember (ay takvimi ile ilgili bir şey) olduğu gibi 12'ye dikkat edin. Ama sadece JRE'de zaten "stok" yazan ayın sabitlerini yeniden icat etmenin nedenini merak ediyorum. –

cevap

162

bu

Months.values()[index] 
+26

Her seferinde değerler dizisinin bir kopyasını klonlayacağına dikkat edin; bu nedenle, performansa duyarlı kodun iç döngüsünde bunu çağırıyorsanız, statik bir kopya oluşturmak ve kullanmak isteyebilirsiniz. –

+0

Kafam karıştı, o zaman neden bir dizi kullanmak istemiyorum? –

+0

@AnudeepSamaiya, her yerde ay yerine [1] uygun enum sabitlerini (Months.JAN) kullanmak isteyebilir. –

7

deneyin EnumMap veya EnumSet kullanmayı deneyin?

+0

+1 benden. OP'yi yanlış yönde göndermekten ziyade olası sorunu ele alır. –

+2

Bunun bir argüman olarak bir (tamsayı) indeks kullanarak bir enum tipi değerini alma problemini nasıl çözdüğünü açıklayabilir misiniz? EnumMap, anahtarın enum türü olmasını gerektirir. –

+1

Doğru. Bu soruya hiç cevap vermiyor. –

17

İşte bunu yapmanın üç yolu.

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

'genel statik 'değişebilir (hem dizi hem de olmayanlar). Euw. Ve bir 'IllegalArgumentException' bir 'null' bombasını geri döndürmekten çok daha anlamlı olur. –

+0

yep. asla böyle yapacağımı asla söylemedim. –

1

ben sadece aynı denenmiş ve aşağıdaki çözüm geldi:

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

sınıf bir dizide içinde kaydedilir kendi değerleri var, ve ben indexposition de enum almak için dizi kullanın. Dizilerin Yukarıda belirtildiği gibi size başlamak Dizininizi istiyorsanız, 0'dan saymaya başlar '1' basitçe bu iki yöntemlerini değiştirmek: my Main İçinde

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

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

Ben

public static void main(String[] args) { 
    int i = Countries.listGetLastIndex(); 
    Countries currCountry = Countries.getCountry(i); 
} 
ile gerekli ülkeler-nesne olsun Bu ülkedeki son ülkeye currCountry'yi ayarlayan

. Bu durumda Ülkeler.KENTUCKY.

Sadece bu kodu nesnelerinizi almak için kodlanmış belirtiler kullanıyorsanız ArrayOutOfBoundsExceptions tarafından çok etkilendiğini unutmayın.