这段代码会带来什么修改?在最后几行中,我应该使用更多 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。我认为switch-case结构不适用于Strings。
后来编辑2:
一个开关与字节一起工作,简短, char和int原始数据类型。它 也适用于枚举类型 (在类和继承中讨论) 还有一些“包装”的特殊课程 某些原始类型:角色, 字节,短整数和整数(讨论 在简单数据对象中。)
答案 0 :(得分:10)
即使您不使用switch语句,是的,如果要避免无用的比较,请使用else:如果第一个 if ,则不希望在此处评估所有其他ifs因为他们总是假的。此外,您不需要缩进每个,如果使最后一个块如此缩进,以至于在没有滚动的情况下无法看到它,以下代码是完全可读的:
if (action.equals("opt1")) {
}
else if (action.equals("opt2")) {
}
else if (action.equals("opt3")) {
}
else {
}
答案 1 :(得分:5)
使用字符串作为键类型的字典,并将*作为值类型委托。 - 从使用字符串中检索方法将需要O(1 + load)。
在类的构造函数中填充字典。
答案 2 :(得分:4)
假设您的语言支持切换字符串,请使用switch语句。
switch(action)
{
case "opt6":
//
break;
case "opt7":
//
...
...
...
}
答案 3 :(得分:4)
在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的实现使用静态hashmap将其String参数映射到枚举值。
答案 4 :(得分:2)
您可以使用开关。
switch (action)
{
case "opt3":
case "opt4":
doSomething;
break;
case "opt5":
doSomething;
break;
default:
doSomeWork;
break;
}
答案 5 :(得分:1)
这取决于您的语言,但它看起来像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语句不能提供足够的清晰度或灵活性(正如Victor在下面提到的那样,在某些语言中不适用于字符串)。大多数编程语言都会用“else if”来表示,而不是写
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
。
答案 6 :(得分:1)
如果您指定语言可能会有所帮助......因为它看起来像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
。无论如何,我希望我能帮忙!
答案 7 :(得分:1)
我只是将其清理为一系列if / else语句:
if(action.equals("opt1"))
{
// something
}
else if (action.equals("opt2"))
{
// something
}
else if (action.equals("opt3"))
{
// something
}
etc...
答案 8 :(得分:0)
建议使用switch语句的答案是要走的路。切换语句比现在的if
和if...else
语句更容易阅读。
简单的比较很快,//something
代码不会针对所有情况执行,因此您可以跳过“优化”并选择“可维护性”。
当然,假设action.equals()
方法像==
那样做了一些微不足道的事情。如果action.equals()
价格昂贵,那么您还有其他问题。
答案 9 :(得分:0)
实际上这取决于分支分析。如果99%的决定是“opt1”,那么这段代码就已经相当不错了。如果99%的决定都是“opt6”,那么这段代码就是丑陋的。
如果您经常“opt6”并且很少“opt1”在第一次比较中加入“opt6”,并根据执行数据流中字符串的频率对以下比较进行排序。
如果您有很多选项并且所有选项都具有相同的频率,您可以对选项进行排序并将它们拆分为二进制树的形式,如下所示:
if (action < "opt20")
{
if( action < "opt10" )
{
if( action == "opt4" ) {...}
else if( action == "opt2" ) {...}
else if( action == "opt1" ) {...}
else if( action == "opt8" ) {...}
}
}
else
{
if( action < "opt30 )
{
}
else
{
if( action == "opt38" ) {...}
else if( action == "opt32" ) {...}
}
}
在此示例中,范围拆分将“opt38”和“opt4”所需的比较减少到3.因此,您可以在每个分支中获得log2(n)+1比较。这对于选项的相同频率是最佳的。
不要二进制吐出到最后,最后使用4-10“正常”否则,如果按选项的频率排序的构造。二叉树中的最后两个或三个级别不需要太多进展。
<强>摘要强>
至少对这种比较有两种优化。
二进制决策树由编译器用于大型switch-case结构。但是编译器对选项的频率一无所知。因此,如果一个或两个选项比其他选项更频繁,则根据频率的排序可以对开关盒的使用具有性能益处。在这种情况下,这是一种解决方法:
if (action == "opt5") // Processing a frequent (99%) option first
{
}
else // Processing less frequent options (>1%) second
{
switch( action )
{
case "opt1": ...
case "opt2": ...
}
}
警告强>
在完成分析之前不要优化代码,这是非常必要的。最好使用switch-case或者 - 如果是直接的,你的代码保持干净和可读。如果您已经优化了代码,请在代码中添加一些好的注释,这样每个人都可以理解这种丑陋的代码和平。一年之后,您将不会知道分析数据,一些评论将非常有用。
答案 10 :(得分:0)
这样的程序切换通常由多态性更好地处理 - 而不是由字符串表示的动作,表示具有可以专门化的'某事'方法的对象的动作。如果您发现需要将字符串映射到该选项,请使用Map<String,Option>
。
如果你想坚持程序代码,真实代码中的选项都是“optX”:
if ( action.startsWith("opt") && action.length() == 4 ) {
switch ( action.charAt(3) ) {
case '1': something; break;
case '2': something; break;
case '3': something; break;
...
}
}
在类似解析器(破坏字符串是问题域的一部分)之类的东西中会很好,并且应该很快,但不具有内聚性(对象action
与行为之间的连接是基于其表示的部分,而不是对象的任何内在因素)。
答案 11 :(得分:0)
请注意,在switch语句的情况下使用字符串是将在下一版Java中添加的新功能之一。
答案 12 :(得分:0)
如果您发现本机java开关构造过于局限,请查看允许通过将它们与某些hamcrest匹配器进行匹配来声明性地切换任何对象的lambdaj Switcher。