Проверьте сразу несколько .equals () - PullRequest
1 голос
/ 31 января 2012

Я хотел знать, есть ли способ сократить это выражение if с помощью «.equals», чтобы я мог проверять вещи в одной строке вместо нескольких операторов if.

Это отрывок моего текущего длинного кода.(Это то, что я хочу сократить)

if (queryArray[1].equals("+")) { 
     System.out.println("Got +");
 } else if (queryArray[1].equals("-")) {
     System.out.println("Got -");
 } else if (queryArray[1].equals("*")) {
     System.out.println("Got *");
 }

Я пытался сделать это (не работает), чтобы уменьшить количество необходимых строк.

if (queryArray[1].equals("+","-","*")) { 
             System.out.println("Got +");
         }

И даже (Не работает):

if (queryArray[1].equals("+" || "-" || "*")) { 
         System.out.println("Got +");
     }

Кроме того, я знаю о или синтаксис "||" в if statements, однако я собираюсь сократить его в методе ".equals()".

Есть ли способ сократить этот код?Спасибо.

Ответы [ 9 ]

5 голосов
/ 31 января 2012

Поскольку вы выполняете только односимвольные сравнения, вы можете сделать switch для queryArray[1].charAt(0).

switch (queryArray[1].charAt(0)) {
    case '+':
      // plus thing
      break;
    case '-':
      // minus thing
      break
    // ... and so on
}

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

2 голосов
/ 31 января 2012

Вы даже можете сделать это таким образом

List<String> list = Arrays.asList("+","-","*");

if(list.contains(queryArray[1]))
  System.out.println("Got "+queryArray[1]);
2 голосов
/ 31 января 2012

С Java 7 вы можете сделать switch для строк:

switch(queryArray[1]) {
  case "+":
  case "*":
  case "-":
     System.out.println("Got " + queryArray[1]);
     break;
  default:
     // do nothing
}
2 голосов
/ 31 января 2012

Во-первых, ваш альтернативный синтаксис внутри .equals() не является допустимым Java.

Если у вас нет более чем нескольких тестов, и в каждом из них есть цикломатическая сложность в каждом условии, нет никаких веских причин делать то, что вы просите.

Тем не менее, вам нужно перевернуть проблему с ног на голову и сделать что-то вроде следующего:

interface Handler { public void handle(); }

final Map<String, Handler> symbols = new HashMap<String, Handler>();
symbols.put("+", new Handler() {
    public void handle() { System.out.println("Got +"); }
};   
symbols.put("-", new Handler() {
    public void handle() { System.out.println("Got -"); }
};
symbols.put("*", new Handler() {
    public void handle() { System.out.println("Got *"); }
}; 

Тогда логические тесты сводятся к:

symbols.get(queryArray[1]).handle();

Это не будет быстрее, чем отдельная конструкция if/elseif/else, но она делает что-то вроде того, что вы ищете, чтобы уменьшить количество строк кода.

Это обычный шаблон объектно-ориентированного проектирования, это вариант шаблона Chain of Responsibility .

Это очень полезно, когда в конструкции if/elseif/else есть много альтернатив и логика в каждой альтернативе сложна.

Это упрощает добавление альтернатив, как реализация интерфейса и добавление альтернативы к Map.

Это также делает обслуживание очень простым. Потому что это способствует инкапсуляции правил и сплоченности логики. Нечто, что полностью теряется в очень больших if/elseif/else блоках.

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

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

Попробуйте это

Map<String,String> resultMap = new HashMap<String,String>();
resultMap.put("+","Got +");
resultMap.put("-","Got -");
resultMap.put("*","Got *");

System.out.println(resultMap.get(queryArray[1]));
0 голосов
/ 31 января 2012

Что-то еще более неясное:

char a = queryArray[1].charAt(0);
if ((a - '*') * (a - '+') * (a - '-') == 0) {
    /* process here. */
}

Скорее бесполезно, если вы хотите сравнить более одного символа.

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

В одной строке ...

if (Arrays.asList("+", "-", "*").contains(queryArray[1])) {
    System.out.println("BINGO!");
}

Это работает, потому что asList имеет параметр varargs.

Однако этот код включает создание и инициализацию нового String[],оборачивая его в новый List и затем перебирая список.Так что не делайте этого, если производительность может быть проблемой.

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

Самое короткое Java-решение, о котором я могу подумать:

System.out.println (Arrays.asList ("+", "-", "*").contains ("-"));
0 голосов
/ 31 января 2012

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

if (queryArray[1].equals("+")) 
{       
    System.out.println("Got +");  
} 
else if (queryArray[1].equals("-")) 
{      
    System.out.println("Got -");  
}
else if (queryArray[1].equals("*")) 
{
    System.out.println("Got *");  
}

Однако Borealid дал конструкцию switch-case, но небольшое изменение логики вызовет множество изменений и, возможно, поиск ошибок.

Ну, я тоже предоставляю решение в тех же строках, но оно также не лучше, чем код, который вы предоставили:

System.out.println(queryArray[1].equals("+")?"Got +"
                  :queryArray[1].equals("-")?"Got -"
                  :queryArray[1].equals("*")?"Got *"
                  :"");

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

И еще одно замечание: операторы || и && должны использоваться с операндами boolean. и перед вызовом проверки API это javadoc: равно

...