多个 if 语句
Posted
技术标签:
【中文标题】多个 if 语句【英文标题】:Multiple if statements 【发布时间】:2012-05-25 13:59:19 【问题描述】:假设我正在使用一个 if 语句来解释十种不同的可能按钮按下,这些按钮会将事件值发送到事件侦听器:
public boolean onTouch(int v) //this is my only listener for all ten buttons
if(event.getAction() == MotionEvent.ACTION_DOWN)
if(v==button_one)pool.play(bass1, 1f,1f, 1, 0, 1f);
if(v==button_two)pool.play(bass2, 1f,1f, 1, 0, 1f);
if(v==button_three)pool.play(bass3, 1f,1f, 1, 0, 1f);
if(v==button_four)pool.play(snare1, 1f,1f, 1, 0, 1f);
if(v==button_five)pool.play(snare2, 1f,1f, 1, 0, 1f);
if(v==button_six)pool.play(snare3, 1f,1f, 1, 0, 1f);
if(v==button_seven)pool.play(hh1, 1f,1f, 1, 0, 1f);
if(v==button_eight)pool.play(hh2, 1f,1f, 1, 0, 1f);
return false;
对这些进行分类会更有效吗?说... 一个用于军鼓的 onClick 事件,一个用于贝司的事件,一个用于踩镲的事件,这样当按下按钮时,程序不必计算每个 if 语句,只有在侦听器中的那个用于触发活动?
【问题讨论】:
我更喜欢这种方式,10 个不同的听众听这么简单的事情似乎太过分了。如果在找到按钮后未评估所有其他行,则您可能可以执行其他操作。 但是这样做,处理程序是否会调用其他元素中的onTouch
事件?
【参考方案1】:
这样的事情呢?
HashMap<int,int> soundMap = new HashMap<int,int>();
soundMap.put(button_one, bass1);
soundMap.put(button_two, bass2);
soundMap.put(button_three, bass3);
soundMap.put(button_four, snare1);
soundMap.put(button_five, snare2);
soundMap.put(button_six, snare3);
soundMap.put(button_seven, hh1);
soundMap.put(button_eight, hh2);
将 HashMap 作为类变量,并在 onCreate 或其他东西中初始化映射。然后你可以将它用于你的听众:
public boolean onTouch(int v)
if(event.getAction() == MotionEvent.ACTION_DOWN)
pool.play(soundMap.get(v), 1f, 1f, 1, 0, 1f);
return false;
这样做的好处是,如果以后要添加更多按钮,只需要用新的声音映射修改映射初始化方法即可;侦听器不需要任何更改。
【讨论】:
【参考方案2】:只是为了在这里添加丰富的建议和意见,并同意之前所有关于“这真的是性能问题”的观点,我会选择使代码最容易阅读和维护的结构,并且任何可能需要维护它的人。通过维护,还要考虑扩展它。如果您想再添加 5 个音垫,3 个月后会发生什么?
减少到最少的行数可能会给您带来几乎无法估量的性能提升,并在您的 APK 中节省几个字节,但在大多数情况下,我会以可读性为代价。
话虽如此,我确实喜欢 kcoppocks 的解决方案。对我来说,这很简短,很优雅,我会怎么做,但是,如果你的经验水平不同,你不能只是看着它说“啊,是的,我明白了”,那么保持你的如果,或者更好,一个开关。
【讨论】:
【参考方案3】:在您知道这是个问题之前,我不会担心将其分解。 switch 将有助于减少重复的if
语句:
public boolean onTouch(int v)
if(event.getAction() == MotionEvent.ACTION_DOWN)
switch (v)
case button_one: pool.play(); break;
case button_two: pool.play(..); break;
...
return false;
【讨论】:
这个网站的反馈速度让我吃惊。我想我会选择 switch 语句作为选项,然后如果我决定加载更多文件,如果没关系,那么我可以放松一下。谢谢大家【参考方案4】:在这种情况下,不必担心性能;条件语句所花费的时间将被它周围的事件处理代码完全相形见绌。绩效的第一至第三定律是衡量、衡量、衡量,我对找到差异的机会持怀疑态度。
我不禁注意到唯一改变的是 pool.play 的第一个参数。 bass1、bass2等与对应的v值有关系吗?
【讨论】:
不,池是一个数组,其中加载了所有声音文件,因此无论您按下哪个按钮,都取决于池播放的文件。第一个参数是唯一可以选择的与音频文件相关的参数,其他是音量、循环设置和浮点值,[我还不完全理解浮点参数] @kcoppock 的答案可能有一个有趣的变化,您可以将池的 ID 与按钮的 ID 相同。唉:这将是一种让你感觉很聪明但对可维护性没有好处的诡计。大多数情况下,kcoppock 所说的。 @Iain:我喜欢这个主意;这肯定是一个不错的解决方案。如果您可以在 XML 中添加与相关声音 ID 相关的标签,那就太好了,但我不知道有没有办法做到这一点。 @KendalH:最后一个浮点参数是播放速度。1.0f
是1:1播放,可以从0.5f
(50%播放速度)到2.0f
(200%播放速度)
我想这已经正常了,但是 Kendal,扩展 View 类(你的按钮)并添加自定义属性来做任何你想做的事情真的很容易。几乎唯一的规则是您可以在 XML 中表达属性的值。请参阅此示例以了解初学者...***.com/questions/5316686/…【参考方案5】:
我认为没有必要,但我肯定会推荐 switch 和 case。您可以订购最常见到最不常见的,但它的变化很小,不会被注意到。通过这些 if 语句根本不需要很长时间。
【讨论】:
【参考方案6】:我不知道这个if
运行了多少次,但对我来说似乎并没有低效。这个布尔测试非常快。
无论如何,如果您确实想让它尽可能高效,我看到了两个选择:
-
最简单的方法:使用
else if
而不是if
。
复杂的一个:使用ActionIf
对象的数组来做你想做的事:
public interface ActionIf
public void go();
public class ActionBass1 implements ActionIf
@Override
public void go()
pool.play(bass1, 1f,1f, 1, 0, 1f);
public class ActionBass2 implements ActionIf
@Override
public void go()
pool.play(bass2, 1f,1f, 1, 0, 1f);
...
public ActionIf[] actions = new ActionBass1(), new Action Bass2(), ...);
public boolean onTouch(int v) //this is my only listener for all ten buttons
if(event.getAction() == MotionEvent.ACTION_DOWN && v >= 0 && v <= (button_eight-button_one))
actions[button_one+v].go();
return false;
【讨论】:
以上是关于多个 if 语句的主要内容,如果未能解决你的问题,请参考以下文章