有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java缩短开关块内case语句中的代码行

我的switch语句中有10个案例。他们每个人做的事情都是一样的,只是作业不同。如果我必须在一个案例块中更改一行代码(在开发过程中),那么我必须手动更改所有其他9个案例

以下是每个案例陈述的场景:

  1. 每个案例都包含一长行代码,其中包含许多函数调用和赋值
  2. 仅变量赋值、函数参数和if语句条件变化
  3. 变量和函数参数的赋值没有模式/顺序
  4. 由于某些原因,添加助手函数并在每个case语句上调用它们几乎是不可能的

我如何优化或缩短这一点

举例说明:

final int CONSTANT_A = 0;
final int CONSTANT_B = 1;
...
final int CONSTANT_J = 10;

int varA = 0;
int varB = 1;
...
int varJ = 10;

int anothervarA = 0;
int anothervarB = 1;
...
int anothervarJ = 10;

int action = 0;

switch(something) {
    case 1:
        ... long lines of code here
        // If I have to change the variables below
        // then I have to update all other variables in
        // other cases below
        varA = CONSTANT_J;
        anothervarA = CONSTANT_B;
        ... another long lines of code here
        int ret = someObject.foo(varA);
        ... do something with ret.
        action = 5;
        break;
    case 2:
        ... long lines of code here
        varB = CONSTANT_I;
        anothervarB = CONSTANT_C
        ... another long lines of code here
        int ret = someObject.foo(varA);
        ... do something with ret.
        action = 100;
        break;
    ...
    ...
    case 9:
        ... long lines of code here
        varI = CONSTANT_B;
        anothervarI = CONSTANT_A;
        ... another long lines of code here
        int ret = someObject.foo(varA);
        ... do something with ret.
        action = 100;
        break;
    case 10:
        ... long lines of code here
        varK = CONSTANT_A;
        anothervarJ = CONSTANT_F;
        ... another long lines of code here
        int ret = someObject.foo(varA);
        ... do something with ret.
        action = 4;
        break;
}

共 (3) 个答案

  1. # 1 楼答案

    考虑到你的标准,我认为你做不了什么。如果调用或分配的内容中没有模式,那么很难对其进行优化。看起来有一些常见的代码可以拉入helper方法中,但是您会说:

    Adding helper functions and calling them on each case statements is almost impossible for some reason.

    我不确定这意味着什么,但是如果你因为某种原因不能创建助手方法,我认为你也无能为力

  2. # 2 楼答案

    除了可能将所有代码分解成一组类(或枚举),并依赖多态性而不是switch来调用正确的类之外,没有任何明显的跳出。例如,将您的案例加载到Map<Integer,Foo>或甚至是List<Foo>中(如果它不是稀疏数组),然后用myFoos.get(something).whatever();替换开关

    至于在完成时分配变量,如果它们是成员变量,可以让foo直接设置它们;如果总是在单线程环境中调用此函数,则可以使用foo.whatever()设置状态,然后使用getter。如果它在多线程环境中,您可以让whatever()返回带有这些getter的新对象。比如:

    FooResult result = myFoos().get(something).getResult(whatever, args);
    varA = result.getA();
    action = result.getAction();
    etc
    
  3. # 3 楼答案

    您可以将共享代码放在switch语句之外,并将switch语句分为多个开关,以便共享代码可以介于以下两个开关之间:

    // declare & initialize variables
    
    //... long lines of code here
    
    // first switch: only assign values
    switch(something) {
        case 1:
            varA = CONSTANT_J;
            anothervarA = CONSTANT_B;
            break;
        // more cases...
    }
    
    //... another long lines of code here
    
    // second switch: only call the method someObject.foo(???);
    switch(something) {
        case 1:
            int ret = someObject.foo(varA);
            break;
        // more cases...
    }
    
    //... do something with ret.
    
    // third switch: assign the action value
    switch(something) {
        case 1:
            action = 5;
            break;
        // more cases...
    }
    

    这使得您只需编写一次重复的代码,而代价是要有多个switch语句,这会添加大量额外的casebreak


    根据具体情况,您可能可以使用数组来完全删除switch语句。例如,您可以创建一个包含所有操作值的数组,然后在索引something - 1处指定action元素:

    int[] actionValues = { 5, 100, \*...,*\ 100, 4};
    action = acionValues[something - 1];
    

    这也可以应用于变量初始化,尽管这会很棘手。您必须将所有变量和常量存储在数组中,并为每种情况找到一个数学模式或硬编码一组规则(每个规则包含常量的索引和要分配给它的变量的索引)。要仍然按名称访问变量和常量(与索引相反),可以使用getter和setter:

    int getVarA() { return varArray[0]; }
    void setVarA(int val) { varArray[0] = val; }
    int getVarB() { return varArray[1]; }
    void setVarB(int val) { varArray[1] = val; }
    int CONSTANT_A() { return constArray[0]; } // no need for a setter
    

    对于第一种情况,规则可能是

    • 将索引9处的常数(常数)分配给索引0处的变量(变量)
    • 将索引1处的常数(常数B)分配给索引26处的变量(另一个变量)

    您可以将这些规则存储在一个数组中,并将每个案例的规则数组存储在一个数组数组中:

    int[][] rules = {
        /* rules for case 1 */
        { 9, 0, 1, 26 }, /* interpret as: const9 -> var0, const1 -> var26 */
        /* rules for other cases */
    };
    

    要“执行”案例的规则:

    int c = something - 1; // give the case a short name to save typing
    varArray[ rules[c][1] ] = constArray[ rules[c][0] ];
    varArray[ rules[c][3] ] = constArray[ rules[c][2] ];