2011-07-14 41 views
64

Tôi có một enum trong Java:Làm cách nào để lấy Giá trị Enum từ chỉ mục trong Java?

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

tôi muốn truy cập các giá trị enum bởi chỉ số, ví dụ

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

Tôi phải làm như thế nào?

+7

Trong khoa học máy tính, các chỉ mục bắt đầu bằng 0, không phải 1 ;-) – fredoverflow

+1

Bạn có chắc chắn muốn? Nói chung, bạn không nên chạm vào thứ tự, ngoài việc thực hiện các cấu trúc dữ liệu cấp thấp (và sau đó, sử dụng các cơ chế thay thế, chẳng hạn như tên, cho sự kiên trì). –

+0

Bạn cũng có thể đã sử dụng các hằng số trong lớp java.util.Calendar. Chúng được đánh số từ 0 - 11 cho tháng 1 - tháng 12. Hãy cẩn thận với 12 vì đó là UnDecember (một số thứ cần làm với âm lịch). Nhưng tôi chỉ tò mò tại sao tái phát minh ra các bánh xe của hằng số tháng mà đã đến "cổ phiếu" trong JRE? –

Trả lời

162

Hãy thử điều này

Months.values()[index] 
+26

Lưu ý rằng sẽ sao chép một bản sao của mảng giá trị mỗi lần, vì vậy nếu bạn đang gọi điều này trong vòng lặp bên trong của mã nhạy cảm hiệu suất, bạn có thể muốn tạo một bản sao tĩnh và sử dụng nó. –

+0

Tôi nhầm lẫn, vậy tại sao tôi không muốn sử dụng một mảng thay thế? –

+0

@AnudeepSamaiya có thể là chúng tôi muốn sử dụng các hằng số enum thích hợp (Months.JAN) trong mã thay vì hàng tháng [1] ở khắp mọi nơi. –

3

Check-out java hướng dẫn về enum (ví dụ với các hành tinh)

http://download.oracle.com/javase/tutorial/java/javaOO/enum.html

+4

Bạn có thể giải thích cách hướng dẫn này giải thích cách giải quyết vấn đề truy xuất một giá trị kiểu enum bằng cách sử dụng chỉ mục (số nguyên) làm đối số không? Cá nhân tôi không thấy điều đó trong hướng dẫn. –

7

Cố gắng sử dụng EnumMap hoặc EnumSet?

+0

+1 từ tôi. Giải quyết vấn đề có khả năng hơn là gửi OP xa hơn theo hướng sai. –

+2

Bạn có thể giải thích cách giải quyết vấn đề truy xuất giá trị loại enum bằng chỉ số (số nguyên) làm đối số không? EnumMap yêu cầu khóa là loại enum. –

+1

Đúng vậy. Điều này không trả lời được câu hỏi nào cả. –

17

Dưới đây là ba cách để thực hiện.

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' mutable (cả mảng và không' '' '). Euw. Và một 'IllegalArgumentException' sẽ có ý nghĩa hơn nhiều so với việc trả về một quả bom' null'. –

+0

yep. không bao giờ nói tôi sẽ làm theo cách này. –

1

Tôi chỉ cố gắng như nhau và đã đưa ra giải pháp sau đây:

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

Lớp có nó giá trị riêng lưu trong một mảng, và tôi sử dụng mảng để có được những enum tại indexposition. Như đã đề cập ở trên mảng bắt đầu đếm từ 0, nếu bạn muốn chỉ số của bạn để bắt đầu từ '1' chỉ cần thay đổi hai phương pháp để:

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

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

Bên trong chính tôi, tôi có được sự cần thiết các nước có đối tượng với

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

đặt currCountry cho quốc gia cuối cùng, trong trường hợp này là Countries.KENTUCKY.

Chỉ cần nhớ mã này rất bị ảnh hưởng bởi ArrayOutOfBoundsExceptions nếu bạn đang sử dụng chỉ báo cứng để lấy đối tượng của bạn.

Các vấn đề liên quan