多个 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 语句的主要内容,如果未能解决你的问题,请参考以下文章

如何在 elisp 'if' 语句中编写多个语句?

多个 if 语句

PHP:在if语句中分配多个变量

命令行中多个 If 和 Else If 语句的问题

合并多个 if 语句

内联中的多个语句 if