Оптимизация if-else / switch-case со строковыми параметрами - PullRequest
4 голосов
/ 08 октября 2009

Какая модификация принесет этот кусок кода? В последних строках я должен использовать больше if-else структур вместо " if-if-if"

if (action.equals("opt1"))
{
    //something
}
else
{
    if (action.equals("opt2"))
    {
        //something
    }
    else
    {
        if ((action.equals("opt3")) || (action.equals("opt4")))
        {
            //something
        }
        if (action.equals("opt5"))
        {
            //something
        }
        if (action.equals("opt6"))
        {
            //something
        }
    }
}

Позднее редактирование: это Java. Я не думаю, что структура переключателя будет работать со строками.

Позже Редактировать 2:

Переключатель работает с байтом, коротким, char и int примитивные типы данных. Это также работает с перечисляемыми типами (обсуждается в классах и наследовании) и несколько специальных классов, которые "обертывают" определенные примитивные типы: характер, Byte, Short и Integer (обсуждается в простых объектах данных).

Ответы [ 13 ]

10 голосов
/ 08 октября 2009

Даже если вы не используете оператор switch, да, используйте else, если хотите избежать бесполезного сравнения: если берется первое , если взято , вы не хотите, чтобы все остальные if оценивались здесь, поскольку они всегда будут ложными. Также вам не нужно делать отступы для каждого , если делает последний блок настолько отступом, что вы не можете увидеть его без прокрутки, следующий код отлично читается:

if (action.equals("opt1")) {
}
else if (action.equals("opt2")) {
}
else if (action.equals("opt3")) {
}
else {
}
5 голосов
/ 08 октября 2009

Использовать словарь со строкой в ​​качестве типа ключа и делегатов * в качестве типа значения. - Извлечение метода из строки будет занимать O (1 + загрузка).

Заполните словарь в конструкторе класса.

  • Java не поддерживает делегат, поэтому для обхода ситуации может потребоваться определить несколько внутренних классов - по одному для каждого случая и передать в качестве значений экземпляр внутренних классов вместо методов.
4 голосов
/ 08 октября 2009

Есть несколько способов сделать это на Java, но вот изящный.

enum Option {
    opt1, opt2, opt3, opt4, opt5, opt6
}

...

switch (Option.valueOf(s)) {
case opt1:
    // do opt1
    break;
case opt2:
    // do opt2
    break;
case opt3: case opt4:
    // do opt3 or opt4
    break;
...
}

Обратите внимание, что valueOf(String) выдаст IllegalArgumentException, если аргумент не является именем одного из членов перечисления. Под капотом реализация valueOf использует статическую хэш-карту для сопоставления аргумента String со значением перечисления.

4 голосов
/ 08 октября 2009

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

switch(action)
{
   case "opt6":
      //
      break;
   case "opt7":
      //
   ...
   ...
   ...
}
2 голосов
/ 08 октября 2009

Вы можете использовать переключатель.

switch (action)
{
 case "opt3":
 case "opt4":
 doSomething;
 break;
 case "opt5":
 doSomething;
 break;
 default:
 doSomeWork;
 break;
}
1 голос
/ 08 октября 2009

Я бы просто очистил это как последовательность операторов if / else:

if(action.equals("opt1"))
{
    // something
}
else if (action.equals("opt2"))
{
    // something
}
else if (action.equals("opt3"))
{
    // something
}
etc...
1 голос
/ 08 октября 2009

Это могло бы помочь, если бы вы указали язык ... Поскольку он выглядит как C ++, вы можете использовать switch.

switch (action) {
   case "opt1":
      // something
      break;
   case "opt2":
      // something
      break;
   ...
}

И если вы захотите использовать операторы if, я думаю, вы могли бы немного улучшить читабельность и производительность, если бы использовали «else if» без фигурных скобок, как в:

if (action.equals("opt1")) {
    //something
} else if (action.equals("opt2")) {
    //something
} else if ((action.equals("opt3")) || (action.equals("opt4"))) {
    //something
} else if (action.equals("opt5")) {
    //something
} else if (action.equals("opt6")) {
    //something
}

Я думаю, что некоторые компиляторы могут оптимизировать else if лучше, чем else { if. В любом случае, я надеюсь, что смогу помочь!

1 голос
/ 08 октября 2009

Это зависит от вашего языка, но выглядит как C, поэтому вы можете попробовать оператор switch:

switch(action)
{
case "opt1":
    // something
    break;

case "opt2":
    // something
    break;

case "opt3":
case "opt4":
    // something
    break;

case "opt5":
    // something
    break;

case "opt6":
    // something
    break;
}

Однако иногда операторы switch не обеспечивают достаточной ясности или гибкости (и, как отметил Виктор ниже, не работают со строками в некоторых языках) Большинство языков программирования будут иметь возможность сказать «иначе, если», а не писать

if (condition1)
{
    ...
}
else
{
    if (condition2)
    {
        ...
    }
    else
    {
        if (condition3)
        {
            ...
        }
        else
        {
            // This can get very indented very fast
        }
    }
}

... с кучей отступов, вы можете написать что-то вроде этого:

if (condition1)
{
    ...
}
else if (condition2)
{
    ...
}
else if (condition3)
{
    ...
}
else
{
    ...
}

В C / C ++, и я верю, что C #, это else if. В Python это elif.

0 голосов
/ 28 марта 2010

Если вы обнаружите, что собственная конструкция переключателя Java слишком ограничена, взгляните на lambdaj Switcher , который позволяет декларативно включать любой объект, сопоставляя его с некоторыми сопоставителями хамкрестов.

0 голосов
/ 08 октября 2009

Обратите внимание, что использование строк в случаях оператора switch является одной из новых функций, которые будут добавлены в следующей версии Java.

См. Project Coin: предложение для строк в коммутаторе

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...