2012-01-27 71 views
3

我正在使用一個將使用超過100個case聲明的開關箱。有沒有限制?開關櫃的最大實施?

案例的用法是針對我的AutoCompleteTextView,android教程的建議。

這裏是我的代碼的一部分,忽略Badrul.class他們將在以後更改。

import android.app.Activity; 
import android.content.Intent; 
import android.os.Bundle; 
import android.view.View; 
import android.widget.AdapterView; 
import android.widget.AdapterView.OnItemClickListener; 
import android.widget.ArrayAdapter; 
import android.widget.AutoCompleteTextView; 
import android.widget.Toast; 

public class Search extends Activity 
{ 
    public void onCreate(Bundle savedInstanceSate) 
    { 
     final AutoCompleteTextView autoComplete; 
     super.onCreate(savedInstanceSate); 
     setContentView(R.layout.searchshop); 

     autoComplete = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView1); 
     ArrayAdapter<String> adapter = new ArrayAdapter<String>(this, R.layout.list_item, shops); 
     autoComplete.setAdapter(adapter); 
     autoComplete.setThreshold(1); 
     autoComplete.setOnItemClickListener(new OnItemClickListener() 
     { 
     @Override 
     public void onItemClick(AdapterView<?> arg0, View arg1, int position, long arg3) 
     { 
      int index=999; 
      for(int i=0;i<shops.length;i++) 
      { 
       if(autoComplete.getText().toString().trim().equals(shops[i])) 
       { 
        index=i; 
        break; 
       } 
      } 

       switch(index) 
       { 
       case 0: 
        startActivity(new Intent(Search.this, Adidas.class)); 
        break; 

       case 1: 
        startActivity(new Intent(Search.this, Affin.class)); 
        break; 
       case 2: 
        startActivity(new Intent(Search.this, AlamArt.class)); 
        break; 
       case 3: 
        startActivity(new Intent(Search.this, AlAmin.class)); 
        break; 
       case 4: 
        startActivity(new Intent(Search.this, Anakku.class)); 
        break; 
       case 5: 
        startActivity(new Intent(Search.this, Anggerik.class)); 
        break; 
       case 6: 
        startActivity(new Intent(Search.this, Asiari.class)); 
        break; 
       case 7: 
        startActivity(new Intent(Search.this, AsterSpring.class)); 
        break; 
       case 8: 
        startActivity(new Intent(Search.this, Audrey.class)); 
        break; 
       case 9: 
        startActivity(new Intent(Search.this, Badrul.class)); 
        break; 
       case 10: 
        startActivity(new Intent(Search.this, Badrul.class)); 
        break; 
       case 11: 
        startActivity(new Intent(Search.this, Badrul.class)); 
        break; 
       default: 
        Toast.makeText(Search.this, "Invalid Selection", Toast.LENGTH_SHORT).show(); 
       } 
      } 
      }); 

     } 
static final String[] shops = new String[] 
      { 
       "Adidas", "Affin Bank ATM", "Alam Art Gallery", "Al Amin Kids", "Anakku", "Anggerik", "Asiari", 
       "Aster Spring", "Audrey", "Badrul Songket", "Bata"}; 
} 
+5

我不知道是否還有更好的解決你的問題......你可以發佈一些代碼嗎? – davioooh 2012-01-27 09:58:46

+0

只要確保沒有任何喜歡使用方法[OOP](http://en.wikipedia.org/wiki/Object-oriented_programming) – 2012-01-27 09:59:49

+0

我不知道任何技術限制,將限制你有超過100 (除非你有數百萬個,在這種情況下,其他一些限制如內存,代碼大小等可能會生效)。但是,如果您有這麼多情況,可能值得質疑設計並尋找更好的選擇。在這種情況下,您可能想在switch語句中提供更多信息。作爲托馬斯說 – Thomas 2012-01-27 10:01:26

回答

6

在達到Java強加的任何限制之前,代碼將變得無法管理。

您是否考慮重構代碼?根據什麼switch語句旨在實現你既可以:

所以你的情況,你會過得更好定義索引值的靜態MapClasses

public class MyClass 
{ 
    private static final Map<Integer, Class> LOOKUP = 
     new HashMap<Integer, Class>(...); 
    static 
    { 
     LOOKUP.put(0, Adidas.class); 
     LOOKUP.put(1, Affin.class); 
     ... 
    } 

    public void onItemClick(...) 
    { 
     ... 
     // Replace switch statement with: 
     if (LOOKUP.containsKey(index)) 
     { 
     startActivity(new Intent(Search.this, LOOKUP.get(index))); 
     } 
     else 
     { 
     Toast.makeText(Search.this, 
         "Invalid Selection", 
         Toast.LENGTH_SHORT).show(); 
     } 
    } 
    ... 
    } 

這使得代碼onItemClick() easi呃閱讀。你可以更進一步,定義一個私有的startActivity()方法,該方法使用索引幷包含所有的switch語句替換代碼。

+0

我想你說的是定義Map m = new HashMap (...);在onItemClick方法中?對不起,但我是新的,你的解決方案似乎很複雜。如果你不介意用你的概念編輯我的代碼。 – 2012-01-27 10:33:42

+0

該映射最好定義爲包含現有代碼的類中的私有靜態最終字段。這樣,每次調用onItemClick方法時都不需要創建它。我會更新我的答案,使其更清晰。 – Andy 2012-01-27 10:45:37

+0

更新了我的代碼。 (用我的舊結構) – 2012-01-28 03:33:55

3

交換機正常工作與字節,短,char和int。所以你有int值+ default的限制。來自here

但我建議更多地考慮建築。最好組織一些接口「表演者」並實現一些表演者(可以作爲內部類)。那麼你只需要有一個數組(地圖),你將擁有這個表演者的條件和實例。這個想法是將數據從算法中分離出來。

而且喲可能會嘗試找到其他模式爲

1

或者你可以看看的戰略格局。例如:

如果它看起來像現在這樣:

switch (calculation type) 
{ 
    case: Fibonacci { ... } 
    case: Pithagoras { ... } 
    ... 
    case 104 : { ... } 
} 

您可以使用策略模式重構它也許是這樣的:

編碼愉快! 戴夫

0

有施加於最大值法長度的限制:Maximum size of a method in java?

否則,作爲一個例子,一個switch 1000情況下,劑型

caseÑ: System.out.println(Ñ); break;

似乎工作。生成的字節碼使用tableswitch指令,這意味着它甚至不應該是低效的。

當然,除非它是自動生成的代碼,否則這將被折磨。替代方案,如

想:

  • 地圖/值數組(如果你的情況下只返回或產生某種形式的數值);
  • 一個將運行必要代碼的地圖/對象數組(取決於確切的條件,最終可能以這種方式代碼更少)。

編輯:

看你的代碼,它似乎,因爲你所有的case語句運行完全相同的類型的代碼,你需要的是通過index訪問的Class[],是這樣的:

Class[] myArray = new Class[...]; 
myArray[0] = Adidas.class; 
//... 

//instead of the switch 
startActivity(new Intent(Search.this, myArray[index])); 

當然,如果有生產這些類其他方式的一種方式,這將是更漂亮的說,如果你有AdidasAffin對象,你就跑getClass(),或者如果你有他們的名字列表並且可以使用Class.forName

0

實現開關時,可以進行許多優化以提高性能,否則必須列出所有開關,直到匹配。

我會在這裏做什麼,是對第一個字符主組交換機則嵌套開關內,因此,如果選擇是ž它不具有循環檢查每名第一

switch(FIRSTCHAR){ 
case A: switch(index){ 
     case 0: ..... break; 
     etc 

     } 
break; 

case B://do the same 
} 

另一種方法是將你的switch語句分解成更小的相等大小的語句。這是更快,因爲字節碼編譯的方式(參見Java性能優化 - 設拉子)

0

一個possibel appraoch是移動/重塑該代碼「責任鏈行話給那些switch語句都不是簡單的回報,一些處理涉及他們等等。

我相信你也沒有使用番石榴的範例(換句話說,你有每個案件一個descret一個,而不是一個普通的處理兩個(多於一個)案件。

0

我不知道到底是什麼你startActivity()方法做,甚至不知道該怎麼Intent對象實現的,但我認爲解決您的問題的另一種方式可以是:

  • 定義超級或稱爲Shop的接口(例如);
  • 繼承所有的類,如Adidas或從Affin;
  • 調用每個類的具體實現方法startActivity();

例如:

public interface Shop 
{ 
    void startActivity(Intent i); 
} 

然後,對於每一類...

public class Adidas implements Shop 
{ 
    public Adidas(){ 
     // ... 
    } 

    public void startActivity(Intent i) 
    { 
     // specific implementation 
    } 
} 

最後,在你的客戶端代碼

Shop[] shops = new Shop[]{ new Adidas(), new Affin(), ... }; 

for (Shop shop : shops) 
{ 
    shop.startActivity(new Intent(Search.this)); 
}