2012-01-31 3 views
1

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

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

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()» ,

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

ответ

5

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

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

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

2

Прежде всего ваш альтернативный синтаксис внутри .equals() недействителен Java.

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

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

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 Pattern.

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

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

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

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

0

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

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 *" 
        :""); 

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

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

2

С Java 7, вы можете сделать switch на струнах:

switch(queryArray[1]) { 
    case "+": 
    case "*": 
    case "-": 
    System.out.println("Got " + queryArray[1]); 
    break; 
    default: 
    // do nothing 
} 
2

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

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

if(list.contains(queryArray[1])) 
    System.out.println("Got "+queryArray[1]); 
+0

Разработает ли компилятор JRE-оптимизатора для создания списка здесь? –

1

Try это

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

не самый красивый способ для данного примера с тремя случаями, но в большем числе случаев это на самом деле аккуратное решение, ИМХО :) – posdef

0

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

System.out.println (Arrays.asList ("+", "-", "*").contains ("-")); 
0

На одной линии ...

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

Это работает, потому что asList имеет параметр с переменным числом аргументов.

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

0

что-то еще более неясным:

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

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

Смежные вопросы