2010-07-29 24 views
6

Có thể xác định một cái gì đó như thế này trong java?Số cho mỗi mục enum?

C# mã:

public enum Character 
{ 
    A = 1, 

    B = 2, 

    C = 4, 

    D = 8 

} 


... 

Character ch = /* from user */ 

if(ch & Character.A) 
{ 
    // some operation... 
} 

ví dụ nếu ch thiết lập để Character.B sau đó kết quả của if sẽ false:

ch = 00000000 00000000 00000000 00000010 
A = 00000000 00000000 00000000 00000001 
------------------------------------------ 
& 00000000 00000000 00000000 00000000 

Tôi muốn thực hiện một cái gì đó như thế! Có thể nào trong Java?

Trả lời

17

Vâng, bạn có thể gần làm điều đó:

public enum CharEnum // Let's avoid java.lang.* clashes 
{ 
    A(1), B(2), C(4), D(8); 

    private final int mask; 

    private CharEnum(int mask) 
    { 
     this.mask = mask; 
    } 

    public int getMask() 
    { 
     return mask; 
    } 
} 

Sau đó:

CharEnum ch = /* from user */ 

if ((ch.getMask() & CharEnum.A.getMask()) > 0) 
{ 
    // some operation... 
} 

Điều này có thể hữu ích trong một số trường hợp, nhưng như Michael nói bạn chắc chắn nên xem xét EnumSet cho chung tùy chọn "đặt giá trị".

Nếu bạn làm quyết định để đi cho một enum với các giá trị, bạn có thể đặt thêm logic trong enum bản thân:

public enum CharEnum 
{ 
    // Other code as before 

    public boolean overlapsWith(CharEnum ch) 
    { 
     return (ch.mask & mask) > 0; 
    } 
} 
+0

Bạn nên thêm một số dấu ngoặc đơn ở đó: 'if ((ch.getMask() & CharEnum.A.getMask())> 0)' –

+0

@True Soft: Cố định, cảm ơn. –

4

(Tất nhiên, việc lựa chọn Character như tên của enum của bạn là rất khó hiểu vì nó tạo ra một cuộc xung đột với java.lang.Character được tự động nhập khẩu vào mỗi đơn vị biên soạn)

Bạn có thể sử dụng phương pháp thứ tự() để có được số nguyên được liên kết với hằng số enum. Dù sao, tôi có một cảm giác rằng những gì bạn đang cố gắng đạt được có thể được thực hiện bằng phương pháp enum xác định. Ý tôi là, enum của Java mạnh hơn C/C++ vì bạn có thể kết hợp hành vi với chúng.

public enum Chr { 
    A { 
     @Override public void doSomething(int c) { 
     // some operation ... 
     } 
    }, 
    B, 
    C, 
    D; 

    public void doSomething(int c) { 
     // some default behavior 
    } 
    } 

Tiếp theo nhận xét của bạn:

Bạn có thể định nghĩa một lĩnh vực mà sẽ giữ giá trị này, và có constructor khởi tạo nó, như sau:

public enum Chr { 
    A(1), 
    B(2), 
    C(4), 
    D(8) 
    ; 

    public Chr(int n) { value = n; }   
    public final int value; 
    } 



    Character ch = ... // from user 
    if(ch & Chr.A.value) { 
    ... 
    } 
2

Bạn có thể làm một cái gì đó như thế sử dụng Enum.ordinal(), nhưng nó sẽ là thiết kế thực sự tồi. Bạn nên sử dụng == để so sánh bình đẳng và EnumSet cho các hoạt động đã đặt.

1

Tôi đồng ý với Itay, và để có được một chút nữa tôi sẽ giới thiệu việc đọc Effective Java Second Edition có một chương đầy đủ thực sự thú vị trên các môi trường Java.

1

Tôi đồng ý với Michael Borgwardt và Jon Skeet rằng EnumSet đáng xem. Tôi đã chọn EnumSet qua các thao tác bitwise như bạn đã có, vì vậy tôi sẽ trình bày cách sử dụng EnumSet.

 

Dường như Character bạn enum (chúng ta hãy gọi nó CharEnum từ giờ trở đi) CharEnum đang được sử dụng như một trường bit, trong đó mỗi enum có một giá trị int chỉ với một chút thiết lập:

A = 00000000 00000000 00000000 00000001 
B = 00000000 00000000 00000000 00000010 
C = 00000000 00000000 00000000 00000100 
D = 00000000 00000000 00000000 00001000 

Điều này rất giống với những gì mà EnumSet làm cho bạn; nó có một vector bit nội bộ tự động gán mỗi enum cho một bit trên long. Như JavaDoc cho nó nói, "Hiệu suất không gian và thời gian của lớp này phải đủ tốt để cho phép sử dụng nó như là một sự thay thế an toàn, chất lượng cao cho các cờ bit" dựa trên int truyền thống. "

Đây là một ví dụ về cách sử dụng nó

public enum CharEnum { 
    A, B, C, D; 
} 

và sau đó

EnumSet<CharEnum> ch = /* from user */ 

if (ch.contains(CharEnum.A)) { 
    // some operation... 
} 

Không cần phải chỉ định bit bất cứ nơi nào, vì vậy nó là mã đơn giản hơn nhiều!

Cảnh báo: điều này chỉ hoạt động vì các giá trị enum trong ví dụ C# của bạn chỉ có một bit đặt mỗi. Nếu bạn có giá trị enum như sau:

E = 00011000 01110111 11100101 10000101 

thì EnumSet sẽ không phù hợp. Trong trường hợp đó, bạn nên xem xét một trong các câu trả lời khác ở đây.

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