if-else和switch语句的替代方案

时间:2014-04-09 05:00:36

标签: java javascript conditional-statements

我在Java中有以下代码:

public void doSomething(int i) {
    if (i == 12) {
        // order should be same
        up();
        left();
        stop();
    }
    if (i == 304) {
        // order should be same
        right();
        up();
        stop();
    }
    if (i == 962) {
        // order should be same
        down();
        left();
        up();
        stop();
    }
}
// similar code can be done using switch case statements.
// all the function can have any functionality and might not resemble to the name given to them.

现在,如果我被要求不使用if-else和switch case语句,那么可以做些什么呢?代码可以用Java或JavaScript完成。

10 个答案:

答案 0 :(得分:27)

如果您可以使用JavaScript,则可以使用具有以下功能的对象:

function doSomething(i) {
  var obj = {};

  obj[12] = function () {
    // order should be same
    up();
    left();
    stop();
  };
  obj[304] = function () {
    // order should be same
    right();
    up();
    stop();
  };
  obj[962] = function () {
    // order should be same
    down();
    left();
    up();
    stop();
  };

  // apparently we can't use any conditional statements
  try {
    obj[i]();
  } catch (e) {}
}

如果仅允许ifswitch语句,请将所有if语句替换为逻辑AND运算符(&&):

function doSomething(i) {
  (i == 12) && (
    // order should be same
    up(),
    left(),
    stop()
  );

  (i == 304) && (
    // order should be same
    right(),
    up(),
    stop()
  );

  (i == 962) && (
    // order should be same
    down(),
    left(),
    up(),
    stop()
  );
}

答案 1 :(得分:16)

以下是在JavaScript中实现此目的的简单方法:

function up()    { console.log("up");    }
function down()  { console.log("down");  }
function left()  { console.log("left");  }
function right() { console.log("right"); }
function stop()  { console.log("stop");  }

var fnmaps = {
    12:  [up, left, stop],
    304: [right, up, stop],
    962: [down, left, up, stop]
};

function doSomething(i) {
    var fnmap = fnmaps[i] || [], j;
    for (j = 0; j < fnmap.length; j++) {
        fnmap[j]();
    }
}

doSomething(12);
doSomething(304);
doSomething(962);

只需编辑地图变量即可添加/订购功能。

答案 2 :(得分:12)

您可以制作输入操作的字典。在Java中,这将是Map<Integer, Runnable>,例如*:

map.put(12, () -> {
    up();
    left();
    stop();
});

然后,您可以获取相应的Runnable并运行它:

Runnable action = map.get(i);
if (action != null) {
    action.run();
} else {
    // some default action
    // This is the "default" case in a switch, or the "else" in an if-else
}

if-else绝对没有必要,但没有它,如果NullPointerException不是预期值,你就会获得i - 也就是说,您放入地图的其中一个值。

这个想法在JavaScript中类似,但是使用对象而不是Map,函数(可能是匿名的)而不是Runnable等等。


此代码适用于Java 8.在Java 7及以下版本中,您可以:

map.put(12, new Runnable() {
    @Override
    public void run() {
        up();
        left();
        stop();
    }
});

答案 3 :(得分:5)

娃哈哈哈哈,你救了我的一天:)这应该工作,现在没办法测试..

public void doSomething(int i) {

try {
    int x = 1/(12-i); // fails for i==12
} catch (ArithmeticException e) {
        up();
        left();
        stop();
}

依此类推,享受!

答案 4 :(得分:4)

然后用while和break来做,没有其他方法没有条件检查

public void doSomething(int i) {

while(i == 12) {
// order should be same
    up();
    left();
    stop();
break;
    }

while(i == 304) {
// order should be same
    right();
    up();
    stop();
break;
    }

while(i == 962) {
// order should be same
    down();
    left();
    up();
    stop();
break;
    }
}

答案 5 :(得分:1)

看,自然你应该用条件表达式检查一个条件语句! 现在,如果你不想这样做,你可以不自然地这样做:

首先对所有方法(向上,向下,......)执行此操作

java.lang.reflect.Method method;
try {
  method = obj.getClass().getMethod(methodName, param1.class, param2.class, ..);
} catch (SecurityException e) {
  // ...
} catch (NoSuchMethodException e) {
  // ...
}

而不是传递给doSomething的整数,使用包含要调用的方法名称的数组,并在for循环中调用每个方法:

然后通过调用

调用该方法
try {
  method.invoke(obj, arg1, arg2,...);
} catch (IllegalArgumentException e) {
} catch (IllegalAccessException e) {
} catch (InvocationTargetException e) {

不幸的是,Java没有委托

答案 6 :(得分:1)

对于js你可以试试这个:

// define ur actions here
var actions = {
  "12" : function () { up(); left(); stop(); },
  "304" : function () { right(); up(); stop(); },
  "962" : function () { down(); left(); up(); stop(); }
};

function doSomething(i) {
  var fn = actions[i];
  try {
    fn();
  } catch (err) {
    console.error(err);
  }
}
//
doSomething(12); //invoke here

答案 7 :(得分:1)

使用OOP技术可以解决这个问题。

在java中它看起来像这样:

public abstract class AObject{
   public abstract  void doSomething();
   public void  up(){
      //do something here
   }
   public void down(){
      //do something here
   }
   public void left(){
      //do something here
   }
   public void right(){
      //do something here
   }       
   public void stop(){
      //do something here
   }     
}


public class AObject12 extends AObject{
   public void doSomething(){
      up();
      left();
      stop();
   }
}

public class AObject304 extends AObject{
   public void doSomething(){
      right();
      up();
      stop();
   }
}

public class AObject962 extends AObject{
   public void doSomething(){
      down();
      left();
      up();
      stop();
   }
}

在具体类的实例上执行doSomething将触发相应的行为。如果/其他是必要的,那就不多了。请参阅下面的代码示例:

AObject A12 = new AObject12();
A12.doSomething();
// Will run Up left stop in that order

AObject A304 = new AObject304();
A304.doSomething();
// Will run right Up stop in that order

AObject A962 = new AObject962();
A962.doSomething();
// Will run down left up stop in that order

有关此类编程的更多信息,请访问:http://en.wikipedia.org/wiki/Polymorphism_%28computer_science%29

如果您希望能够动态更改对象的行为,可以考虑应用状态模式:http://en.wikipedia.org/wiki/State_pattern

答案 8 :(得分:0)

在Java中,这应该有用..

public class IfTest {

    public static void main(String[] args) {
        IfTest ifTest = new IfTest();

        ifTest.doSomething(12);
        ifTest.doSomeThingWithoutIf(12);

        ifTest.doSomething(304);
        ifTest.doSomeThingWithoutIf(304);

        ifTest.doSomething(962);
        ifTest.doSomeThingWithoutIf(962);

        ifTest.doSomething(42);
        ifTest.doSomeThingWithoutIf(42);
    }

    public void doSomeThingWithoutIf(int i) {


        boolean x = i == 12 ? f12() : (i == 304 ? f304() : (i == 962 ? f962() : false));
    }

    public boolean f12() {

        up();
        left();
        stop();

        return true;
    }

    public boolean f304() {

        right();
        up();
        stop();
        return true;
    }

    public boolean f962() {

        down();
        left();
        up();
        stop();

        return true;
    }

    public void doSomething(int i) {

        if(i == 12) {
            // order should be same
            up();
            left();
            stop();
        }

        if(i == 304) {
            // order should be same
            right();
            up();
            stop();
        }

        if(i == 962) {
            // order should be same
            down();
            left();
            up();
            stop();
        }
    }

    private boolean retfalse() {
        return false;
    }

    private void down() {
        System.out.println("down");
    }

    private void right() {
        System.out.println("right");
    }

    private void stop() {
        System.out.println("stop");
    }

    private void left() {
        System.out.println("left");
    }

    private void up() {
        System.out.println("up");
    }
}

答案 9 :(得分:0)

通过播放逻辑AND运算符的短路,可以在JAVA中实现所需的行为,如下所示:

public static Boolean seq12() {
    // order should be same
    up();
    left();
    stop();
    return true;
}
public static Boolean seq304() {
    // order should be same
    right();
    up();
    stop();
    return true;
}
public static Boolean seq962() {
    // order should be same
    down();
    left();
    up();
    stop();
    return true;
}

public static void doSomething(int i) {
    Boolean tmp;
    tmp = (i == 12 && seq12());
    tmp = (i == 304 && seq304());
    tmp = (i == 962 && seq962());
}

这段代码很简单,依赖于逻辑AND运算符仅在第一个操作数为 true 时才计算第二个操作数的事实。