用Java替换switch语句

用Java替换switch语句,java,switch-statement,Java,Switch Statement,我一直在想,是否有一种方法可以替换当前的switch语句。下面是我的代码示例,尽管我的语句要长得多,而且只会变得更大。switch方法通过文件读取器被调用,因此它读取一行,然后使用指定的值调用此函数 public static void example(String action, String from, String to){ switch (action) { case ("run"): runTo(from,to);

我一直在想,是否有一种方法可以替换当前的switch语句。下面是我的代码示例,尽管我的语句要长得多,而且只会变得更大。switch方法通过文件读取器被调用,因此它读取一行,然后使用指定的值调用此函数

public static void example(String action, String from, String to){
 switch (action) {
           case ("run"):
                runTo(from,to);
                break;
           case ("walk"):
                walkTo(from,to);
                break;
           case ("hide"):
                hideAt(to);
                break;
            }
 }
编辑: 我很好奇是否有更好的方法来代替上面的场景中使用switch语句


我对示例进行了一些更新,使其更有意义。有些方法调用不需要使用所有参数。

我不完全确定您想要实现什么。 如果你不想继续添加新的

case ("ccc"):
  Lmn(b,c,i);
  break;         
街区


您可以在
HashMap
中散列方法,并使用键从映射中获取方法并执行它。

用方法调用替换开关绝对不是完全的nonesence@Stultuske。通常使用方法继承,因此具有相同父类的不同子类重写常规方法,并且不必检查子类的类型


另一方面,您的案例看起来像工厂方法,但参数有点混杂。我建议使用
String
Map
映射到包装器构造函数。对于“ccc”的情况,您必须考虑其他因素(例如默认参数),或者始终使用未使用的参数
i

如果在同一变量上有重复次数,比如在方法
f
g
h
中。然后你可以把事情从里到外:

void f(String a) {
    switch (a) {
    case "aaa": ... ; break;
    ...
    }
}

void g(String a) {
    switch (a) {
    case "aaa": ... ; break;
    case "bbb": ... ; break;
    case "ccc": ... ; break;
    ...
    }
}

void h(String a) {
    switch (a) {
    case "aaa": ... ; break;
    ...
    }
}
可以按以下方式定向处理对象:

class C {
    public f() { }
    public g() { }
    public h() { }
}

class Aaa extends C {
    @Override
    public f() { test3(b,c); } // Or even just the body of test3
    @Override
    public g() { }
    @Override
    public h() { }
}

class Bbb extends C {}
class Ccc extends C {}
然后,一旦必须提供特定的C:

    C c;
    switch (a) {
    case "aaa": c = new Aaa(); break;
    case "bbb": c = new Bbb(); break;
    case "ccc": c = new Ccc(); break;
    ...
    }

    c.f(...);

    c.g(...);

    c.h(...);
这看起来是间接的,但实际上提高了开发质量。 添加新案例并不意味着搜索所有开关案例

一个案例的代码(“aaa”)都在一个类中,有自己的专用字段。
这可以简化事情并提供更好的概述。

摆脱switch的一个可能选项是使用函数的hashmap:

private String stringMethod(final String action, final String source) {

    final Function<String, String> toLowerFunction = String::toLowerCase;
    final Function<String, String> toUpperFunction = String::toUpperCase;

    final HashMap<String, Function<String, String>> stringFunctions = new HashMap<>();
    stringFunctions.put("toLower", toLowerFunction);
    stringFunctions.put("toUpper", toUpperFunction);

    return stringFunctions.get(action).apply(source);
}
私有字符串stringMethod(最终字符串操作,最终字符串源){
最终函数toLowerFunction=String::toLowerCase;
最终函数toUpperFunction=String::toUpperCase;
final HashMap stringFunctions=新HashMap();
stringFunctions.put(“toLower”,toLowerFunction);
put(“toUpper”,toUpperFunction);
返回stringFunctions.get(action).apply(source);
}

对于Java 7及以下版本,我们可以声明用于函数实现的接口

对于Java 8+我们可以使用函数接口

接口:

public interface FunctionExecutor {
    public Object execute(String from,String to);

}
函数上下文:

public class FunctionContect {
   HashMap<String, FunctionExecutor> context=new HashMap<String, FunctionExecutor>();

    public void register(String name,FunctionExecutor function){
        context.put(name, function);
    }

   public Object call(String name,String from,String to){
      return    context.get(name).execute(from, to);
   }

   public FunctionExecutor get(String name){
      return context.get(name);
   }

  }
注册功能:

    FunctionContect contex = new FunctionContect();
    contex.register("run", new RunFunctionImpl());
    contex.register("walk", new WalkFunctionImpl());
    contex.register("hide", new HideFunctionImpl());
调用函数

 context.call(action, from, to);


您可能想签出。使用
地图
。很抱歉,这是一个措辞糟糕的标题,我对开发非常陌生,并且仍在努力学习。我试图替换switch语句,其中每个案例调用不同的方法。这里的真正答案是退后一步,看看您实际想要解决的问题。在我看来,拥有这样一个开关的想法,以及在你的方法上有如此多的参数,是一种异味。但是我们不应该纠正症状,而是要了解真正的问题,并看看如何最好地解决它。@GhostCat,你可以使用lambas@ZhenyaM对但答案应该是这样的,并给出一个例子,说明对于使用不同参数的方法如何做到这一点。这就是我要说的:对于一个新手来说,阅读这个答案没有太多有用的内容。我可以不断添加新的case语句,但我很想知道是否有更好的方法来创建一个很长的case语句。@BD1:如果您需要常量的调度程序:使用switch-clean,专门为此而设计的。但就像幽灵猫说的:退后一步,想想你真正需要什么。视情况而定,其他方法可能更合适。
 context.call(action, from, to);
 context.get(action).execute(from,to);