2012-05-02 17 views
24

Tôi có đoạn mã sau:Giảm lệnh if-else trong Java

void f(String t) 
{ 
    if(t.equals("a")) 
    { 
    someObject.setType(ObjectType.TYPE_A); 
    } 
else if(t.equals("b")) 
    { 
    someObject.setType(ObjectType.TYPE_B); 
    } 

// 50 more similar code 

} 

Có cách nào đơn giản để ghi lại các điều kiện if-else như vậy là không có nhiều mã?

Trả lời

50

Bạn nên sử dụng thứ gì đó để loại bỏ sự lặp lại someObject.setType(ObjectType....)) Nếu ObjectTypeenum, sau đó viết phương thức tương tự với valueOf để đạt được điều đó. Xem nếu bạn thích loại hình giải pháp:

void f(String t) { someObject.setType(ObjectType.byName(t)); } 

enum ObjectType { 
    TYPE_A, TYPE_B; 
    public static ObjectType byName(String name) { 
    return valueOf("TYPE_" + name.toUpperCase()); 
    } 
} 
+2

Brilliant .. Tôi không biết về phương pháp 'valueOf' .. cảm ơn .. – Asha

+2

Không chọn nit, bạn chỉ cần cẩn thận với việc xử lý ngoại lệ tại đây; Bạn phải bọc giá trị trả về trong một khối try-catch, để xử lý các kịch bản rác. – questzen

+0

@questzen Chắc chắn, đây chỉ là phác thảo cơ bản. Tùy thuộc vào mong muốn có nhiều cách tiếp cận khác nhau để xử lý rác thải. Cá nhân tôi thường thích ngoại lệ thô nhất (nếu nó thực sự là một lỗi để vượt qua trong thùng rác). Điều đó cung cấp cho bạn thông tin gỡ lỗi trực tiếp nhất. –

15

Sử dụng Map (bạn sẽ phải điền) bản đồ từ String cho bất kỳ loại giá trị ObjectType.TYPE_x của bạn.

+0

Vâng, đó là những gì tôi đã suy nghĩ quá. Nhưng chỉ có nghi ngờ tôi đã có bộ nhớ cần thiết để lưu trữ những dây và tra cứu cần thiết để có được loại. Có không có cách nào khác? – Asha

+2

@Asha các chuỗi trong bản đồ (vì chúng được tập trung) sẽ không chiếm nhiều không gian hơn các chuỗi ký tự. Thời gian tra cứu sẽ bị giảm vì việc tra cứu bản đồ sẽ là 'O (log n)' thay vì 'O (n)'. – Alnitak

+0

@Alnitak Sử dụng 'HashMap' thậm chí có thể nhận được' O (1) '. –

4

Nếu bạn có thể cấu trúc lại t thành một char, bạn có thể sử dụng switch thay vì (Java 6):

void f(char t) { 

    switch(t) { 

    case 'a`: 
     someObject.setType(ObjectType.TYPE_A); 
     break; 
    case 'b': 
     someObject.setType(ObjectType.TYPE_B); 
     break; 

    // ... 

    } 

} 

Như Marko chỉ ra, bạn có thể đi với String cũng bằng Java 7.

Nó không ngắn hơn, nhưng thanh lịch hơn. Hơn nữa, tôi nghĩ rằng nó có thể nhanh hơn, vì switch hoạt động gần với O(1) với các bảng nhảy (Ai đó có thể xác nhận điều này có đúng không?), Cho dù một số câu hỏi ifO(n).

Triển khai phức tạp hơn nhiều so với chỉ một đơn setType bạn cũng có thể nghĩ đến việc triển khai State Pattern.

14

tôi sẽ thêm này như là một chức năng của enum:

public enum ObjectType { 
    TYPE_A("a"), 
    TYPE_B("b"); 

    private String stringType; 

    private ObjectType(String stringType) { 
     this.stringType = stringType; 
    } 

    public String getStringType() { 
     return this.stringType; 
    } 

    public static ObjectType fromStringType(String s) { 
     for (ObjectType type : ObjectType.values()) { 
      if (type.stringType.equals(s)) { 
       return type; 
      } 
     } 
     throw new IllegalArgumentException("No ObjectType with stringType " + s); 
    } 
} 

... 

void f(String t) { 
    someObject.setType(ObjectType.fromStringType(t)); 
} 
+0

Đây là phương pháp tôi thường sử dụng. Tốt hơn là dựa vào các tên liên tục vì nó linh hoạt hơn và khó phá vỡ hơn. – Malcolm

2

1.You có thể đi cho Chuyển tuyên bố nếu bạn có số nếu có điều kiện hơn 3.

2. bạn có thể chuyển đổi các câu lệnh if else của mình thành ternary operations

1

Các đề xuất khác là tuyệt vời - đặc biệt là thông minh và bản đồ thông minh hơn. Nhưng việc cấu trúc lại cơ bản nhất đầu tiên tôi sẽ giải quyết ở đây là trích xuất một phương thức để trả về enum một cách trực tiếp và có người gọi thực hiện không có gì nhiều hơn setType cho giá trị trả về của phương thức đó.

void f(String t) { 
    final ObjectType type = findType(t); 
    if (type != null) 
    someObject.setType(type); 
    } 

ObjectType findType(String t) { 
    if (t.equals("a")) return ObjectType.TYPE_A; 
    if (t.equals("b")) return ObjectType.TYPE_B; 
    // 50 more similar code 
    } 

Trong một số trường hợp, điều này sẽ đầy đủ và tự nó; ở những người khác, phương pháp findType() có thể dẫn bạn đến một giải pháp dựa trên bản đồ hoặc dựa trên enum đơn giản.