Каковы максимальные случаи в инструкции switch? (Java) [дубликат]

Следуя предложению Джошуа, вы можете подсчитать количество наблюдений в вашем фрейме df, где Year = 2007 и Month = Nov (если они столбцы):

nrow(df[,df$YEAR == 2007 & df$Month == "Nov"])

и с aggregate, следуя @GregSnow:

aggregate(x ~ Year + Month, data = df, FUN = length)
3
задан Kenneth Lhv 28 January 2012 в 05:33
поделиться

7 ответов

Код станет неуправляемым, прежде чем вы нажмете любой предел, который накладывает 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.

6
ответ дан Andy 21 August 2018 в 19:04
поделиться
  • 1
    Думаю, вы заявляете, что для определения Map & lt; Integer, Class & gt; m = новый HashMap & lt; Integer, Class & gt; (...); в методе onItemClick? Извините, но я новичок, и ваше решение кажется сложным. Если вы не возражаете редактировать мой код с помощью своей концепции. – Kenneth Lhv 27 January 2012 в 12:33
  • 2
    Карта, вероятно, лучше всего определяется как приватное статическое конечное поле в классе, в котором содержится ваш существующий код. Таким образом, его не нужно создавать каждый раз, когда вызывается метод onItemClick. Я уточню свой ответ, чтобы сделать это более ясным. – Andy 27 January 2012 в 12:45
  • 3
    – Kenneth Lhv 28 January 2012 в 05:33

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

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

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

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

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

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

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

Изменить:

По-видимому, глядя на ваш код, поскольку все ваши операторы 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
ответ дан Community 21 August 2018 в 19:04
поделиться

Я не знаю точно, что делает ваш метод 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
ответ дан davioooh 21 August 2018 в 19:04
поделиться

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

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

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

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

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

Happy кодирование! Dave

1
ответ дан dbalakirev 21 August 2018 в 19:04
поделиться

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

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

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

3
ответ дан Fedor Skrynnikov 21 August 2018 в 19:04
поделиться

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

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

0
ответ дан manocha_ak 21 August 2018 в 19:04
поделиться

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

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

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

        }
break;

case B://do the same
}

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

0
ответ дан Sam Palmer 21 August 2018 в 19:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: