Переключить случаи максимальной реализации? - PullRequest
4 голосов
/ 27 января 2012

Я использую один переключатель дел, который будет иметь более 100 заявлений дел.Существуют ли какие-либо ограничения?

Использование кейсов по совету моего 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"};
}

Ответы [ 7 ]

7 голосов
/ 27 января 2012

Код станет неуправляемым, прежде чем вы достигнете какого-либо ограничения, установленного Java.

Рассматривали ли вы рефакторинг кода? В зависимости от того, для чего предназначен оператор switch, вы можете:

Так что в вашем случае вам лучше определить статический Map значений индекса в Classes:

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(). Вы могли бы пойти еще дальше и определить частный метод startActivity(), который принимает используемый индекс и содержит весь код замены оператора switch.

4 голосов
/ 27 января 2012

Switch отлично работает с byte, short, char и int. Таким образом, у вас есть ограничение значений int + default. С здесь

Но я предлагаю больше думать об архитектуре. Лучше организовать некоторый интерфейс «исполнителя» и реализовать некоторое количество этого исполнителя (может быть как внутренние классы) Тогда вам нужно всего лишь иметь массив (карту), где вы будете иметь условия и экземпляры этого исполнителя. Идея состоит в том, чтобы отделить данные от алгоритма.

Также вы можете попытаться найти другие шаблоны для этого

3 голосов
/ 27 января 2012

Существует ограничение на максимальную длину метода: Максимальный размер метода в java?

В противном случае, например, switch с 1000 случаями формы

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

, кажется, работает.В сгенерированном байт-коде используется инструкция tableswitch, что означает, что она не должна быть даже неэффективной.

Конечно, если это не автоматически сгенерированный код, это будет неодобрительно.

Подумайте об альтернативах, таких как:

  • карта / массив значений (если ваши случаи просто возвращают или производят какое-либо значение);
  • карта / массивобъектов, которые будут запускать необходимый код (в зависимости от конкретных условий, вы можете получить меньше кода таким образом).

Редактировать:

Просмотрв вашем коде, похоже, поскольку все ваши операторы case выполняют код одного и того же типа, все, что вам нужно - это Class[], доступ к которому index, что-то вроде:

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

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

И, конечно,было бы лучше, если бы был способ создать эти классы другим способом, скажем, если у вас было Adidas и Affin объектов, и вы запустили getClass() на них, или если у вас был список их имен, и вы могли быиспользуйте Class.forName.

1 голос
/ 27 января 2012

Или вы можете взглянуть на шаблон стратегии.Например:

Если сейчас это выглядит так:

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

Вы можете изменить его с помощью шаблона стратегии, например, так:

CalculationStrategy strategy = strategyFactor.getStrategy(calculation type);
strategy.doCalculation;

Счастливого кодирования!Dave

0 голосов
/ 27 января 2012

Я не знаю точно, что делает ваш метод 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));
}
0 голосов
/ 27 января 2012

Один из возможных подходов - переместить / переделать этот код в "Chain of Responsibility patter, если учесть, что эти операторы switch не просто возвращаются, для них требуется некоторая обработка и т. Д.

Я полагаю, что у вас также нет варианта использования диапазонов гуавы (Другими словами, у вас есть один случай, а не общий процесс для двух (более чем одного) случая.

0 голосов
/ 27 января 2012

При реализации переключателей можно сделать много оптимизаций для повышения производительности, в противном случае вам придется перечислять все переключатели, пока они не совпадут.

Что я хотел бы сделать здесь, так это получить основной набор переключателей для первого символазатем вложенные переключатели внутри, поэтому, если выбор был z, ему не нужно сначала проверять каждое имя

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

        }
break;

case B://do the same
}

Другой способ - разбить ваш оператор switch на меньшие операторы равного размера.Это быстрее благодаря компиляции байт-кода (см. Настройка производительности Java - shirazi)

...