Используйте строку в случае переключения в Java
Мне нужно изменить следующее if
к switch
-case
во время проверки на String
, чтобы улучшить цикломатическую сложность.
String value = some methodx;
if ("apple".equals(value)) {
method1;
}
if ("carrot".equals(value)) {
method2;
}
if ("mango".equals(value)) {
method3;
}
if ("orange".equals(value)) {
method4;
}
Но я не уверен, какую ценность я собираюсь получить.
13 ответов
Java (до версии 7) не поддерживает String в switch/case. Но вы можете достичь желаемого результата, используя перечисление.
private enum Fruit {
apple, carrot, mango, orange;
}
String value; // assume input
Fruit fruit = Fruit.valueOf(value); // surround with try/catch
switch(fruit) {
case apple:
method1;
break;
case carrot:
method2;
break;
// etc...
}
Все сейчас используют хотя бы Java 7, верно? Вот ответ на оригинальную задачу:
String myString = getFruitString();
switch (myString) {
case "apple":
method1();
break;
case "carrot":
method2();
break;
case "mango":
method3();
break;
case "orange":
method4();
break;
}
Заметки
- Операторы case эквивалентны использованию
String.equals
, - Как обычно, при сопоставлении строк учитывается регистр.
- Согласно документации, это обычно быстрее, чем при использовании цепочки
if
-else
заявления (как в ответе Чао).
Научиться использовать else
,
поскольку value
никогда не будет равняться двум неравным строкам одновременно, есть только 5 возможных результатов - по одному для каждого значения, которое вам небезразлично, плюс один для "ничего из вышеперечисленного". Но поскольку ваш код не устраняет тесты, которые не могут пройти, он имеет 16 "возможных" путей (2 ^ количество тестов), из которых большинство никогда не будет выполнено.
С else
, единственные пути, которые существуют - это 5, которые действительно могут произойти.
String value = some methodx;
if ("apple".equals(value )) {
method1;
}
else if ("carrot".equals(value )) {
method2;
}
else if ("mango".equals(value )) {
method3;
}
else if ("orance".equals(value )) {
method4;
}
Или начните использовать JDK 7, который включает в себя возможность использовать строки в switch
заявление. Конечно, Java просто скомпилирует switch
в if
/else
в любом случае, как построить...
Для уменьшения цикломатической сложности используйте карту:
Map<String,Callable<Object>> map = new HashMap < > ( ) ;
map . put ( "apple" , new Callable<Object> () { public Object call ( method1 ( ) ; return null ; } ) ;
...
map . get ( x ) . call ( ) ;
или полиморфизм
Просто чтобы сделать конкретный ответ Эмори, исполняемый код выглядит следующим образом:
Map<String,Callable<USer>> map = new HashMap<String,Callable<User>>();
map.put( "test" , new Callable<User> () { public User call (){ return fillUser("test" ); }} ) ;
map.put( "admin" , new Callable<Utente> () { public Utente call (){ return fillUser("admin" ); }} ) ;
где пользователь является POJO, а затем
User user = map.get(USERNAME).call();
наконец, вызываемый метод где-то:
private User fillUser(String x){
User user = new User();
// set something in User
return user;
}
Вот возможный путь до 1.7, который я не могу рекомендовать:
public class PoorSwitch
{
final static public int poorHash (String s) {
long l = 0L;
for (char c: s.toCharArray ()) {
l = 97*l + c;
}
return (int) l;
}
public static void main (String args[])
{
String param = "foo";
if (args.length == 1)
{
param = args[0];
}
// uncomment these lines, to evaluate your hash
// test ("foo");
// test ("bar");
switch (poorHash (param)) {
// this doesn't work, since you need a literal constant
// so we have to evaluate our hash beforehand:
// case poorHash ("foo"): {
case 970596: {
System.out.println ("Foo!");
break;
}
// case poorHash ("bar"): {
case 931605: {
System.out.println ("Bar!");
break;
}
default: {
System.out.println ("unknown\t" + param);
break;
}
}
}
public static void test (String s)
{
System.out.println ("Hash:\t " + s + " =\t" + poorHash (s));
}
}
Может быть, вы могли бы работать с таким приемом в сгенерированном коде. Еще я не могу рекомендовать это. Не так много, что возможность коллизии хеша заставляет меня беспокоиться, но если что-то перепутать (вырезать и вставить), то трудно найти ошибку. 931605 не очень хорошая документация.
Воспринимайте это как доказательство концепции, как любопытство.
Java 8 поддерживает строку switchcase.
String type = "apple";
switch(type){
case "apple":
//statements
break;
default:
//statements
break; }
Java не поддерживает Switch-case со строкой. Я думаю, что эта ссылка может помочь вам.:)
Мы можем применить Switch только к типу данных, совместимому с типом int:short,Shor,byte,Byte,int,Integer,char,Character или enum.
String name,lname;
name= JOptionPane.showInputDialog(null,"Enter your name");
lname= JOptionPane.showInputDialog(null,"Enter your father name");
if(name.equals("Ahmad")){
JOptionPane.showMessageDialog(null,"welcome "+name);
}
if(lname.equals("Khan"))
JOptionPane.showMessageDialog(null,"Name : "+name +"\nLast name :"+lname );
else {
JOptionPane.showMessageDialog(null,"try again " );
}
}}
Не очень красиво, но вот другой способ:
String runFct =
queryType.equals("eq") ? "method1":
queryType.equals("L_L")? "method2":
queryType.equals("L_R")? "method3":
queryType.equals("L_LR")? "method4":
"method5";
Method m = this.getClass().getMethod(runFct);
m.invoke(this);
String value = someMethod();
switch(0) {
default:
if ("apple".equals(value)) {
method1();
break;
}
if ("carrot".equals(value)) {
method2();
break;
}
if ("mango".equals(value)) {
method3();
break;
}
if ("orance".equals(value)) {
method4();
break;
}
}