【问题标题】:Multiple if statements多个 if 语句
【发布时间】: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 事件?

标签: java android performance button if-statement


【解决方案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 中表达属性的值。请参阅此示例以了解初学者...stackoverflow.com/questions/5316686/…
      【解决方案5】:

      我认为没有必要,但我肯定会推荐 switch 和 case。您可以订购最常见到最不常见的,但它的变化很小,不会被注意到。通过这些 if 语句根本不需要很长时间。

      【讨论】:

        【解决方案6】:

        我不知道这个if 运行了多少次,但对我来说似乎并没有低效。这个布尔测试非常快。 无论如何,如果您确实想让它尽可能高效,我看到了两个选择:

        1. 最简单的方法:使用else if 而不是if
        2. 复杂的一个:使用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;
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2022-01-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多