如何使用带有多个参数的switch()?

时间:2016-06-10 10:47:52

标签: java if-statement switch-statement

我想使用switch代替if-else,因为当有很多if-else时,它会更好。问题在于我有多个论点,所以我不知道如何处理。

以下是我的if-else':

if(frame.height()/2 + margin < pt.y){
            System.out.println("down");
            drone.getCommandManager().down(20).doFor(100);
            drone.getCommandManager().hover();
        }
        else if(frame.height()/2 - margin > pt.y){
            System.out.println("up");
            drone.getCommandManager().up(20).doFor(100);
            drone.getCommandManager().hover();
        }
        else if(frame.width()/2+margin < pt.x){
            drone.getCommandManager().spinRight(30).doFor(33);
            drone.getCommandManager().hover();
            System.out.println("RIGHT");

        }
        else if(frame.width()/2-margin > pt.x){
            drone.getCommandManager().spinLeft(30).doFor(33);
            drone.getCommandManager().hover();
            System.out.println("LEFT");
        }

        else if(frame.width()/2+margin > pt.x && frame.width()/2-margin<pt.x){
            System.out.println("GO");
            drone.getCommandManager().forward(30).doFor(time+2000);
            drone.getCommandManager().hover();
        }

        else{
            drone.getCommandManager().hover();
        }

3 个答案:

答案 0 :(得分:3)

你不能。

switch中的标签必须是编译时可评估的常量表达式,并且必须将完全与正在接通的事物进行比较。

答案 1 :(得分:3)

您可以退一步,阅读TDA原则。

你在这里所做的实质上是:查询某事物的状态,然后决定其他事情应该如何应对。事情是 - 这实际上不是面向对象的思维。

你可以改为:

interface CommandManagerUpdater {
  void updateOnNewDirection(CommandManager);
}

enum Direction { UP, DOWN, ... };

class DirectionDetector {
   Direction getNewDirection(Frame, x, yz, whatever you need)

class CommandManagerUpdaterFactory {
  CommandManagerUpdater generateUpdaterFor(Direction newDirection) {

如果你有上述方法,你可以把整个事情写成:

Direction newDirection = someDetector.getNewDirection(...)
CommandManagerUpdater updater = theFactory.generateUpdaterFor(newDirection);
updater.updateOnNewDirection(commandManager);

长话短说:在OO编程中,你应该避免使用这种if / else / switch语句。相反:你创建适当的OO抽象;并使用工厂和多态。让我对此非常清楚:切换语句解决您的问题。它们只是if / else树的语法上略有改进的版本。

当然,最后,你需要切换“方向”。但是:你把那个开关藏在工厂里面。应该尽可能少地关注知道所有潜在方向。

最后:密切关注代码重复。看看你的代码中有多少次“hoover()”调用 - 大部分都可以消失!你知道,当你为了你的每个方向而一直“胡佛”时;然后你打电话给那个叫无条件地打电话,而不是在你的每个分支中重复n次!

答案 2 :(得分:0)

我完全赞同Jägermeister所说的话。我认为你应该使用适当的OO原则来改进你的代码,但如果你真的想要一个转换......

您应该将您拥有的表达式转换为单个值。您可以使用如下的枚举:

public enum Result {
    A, B, C, D, E, F
}

当然你应该给它有意义的名字!

然后你可以有一个方法将表达式转换为结果:

public Result calculateResult() {
    if (frame.height() / 2 + margin < pt.y) {
        return A;
    } else if (frame.height() / 2 - margin > pt.y) {
        return B;
    } else if (frame.width() / 2 + margin < pt.x) {
        return C;
    } else if (frame.width() / 2 - margin > pt.x) {
        return D;
    } else if (frame.width() / 2 + margin > pt.x && frame.width() / 2 - margin < pt.x) {
        return E;
    } else {
        return F;
    }
}

最后你可以在开关中使用:

switch (calculateResult()) {
    case A:
        System.out.println("down");
        drone.getCommandManager().down(20).doFor(100);
        drone.getCommandManager().hover();
        break;
    case B:
        System.out.println("up");
        drone.getCommandManager().up(20).doFor(100);
        drone.getCommandManager().hover();
        break;
    case C:
        drone.getCommandManager().spinRight(30).doFor(33);
        drone.getCommandManager().hover();
        System.out.println("RIGHT");
        break;
    case D:
        drone.getCommandManager().spinLeft(30).doFor(33);
        drone.getCommandManager().hover();
        System.out.println("LEFT");
        break;
    case E:
        System.out.println("GO");
        drone.getCommandManager().forward(30).doFor(time + 2000);
        drone.getCommandManager().hover();
        break;
    case F:
        drone.getCommandManager().hover();
        break;
}