如何压缩大型switch语句

Loo*_*oom 5 java switch-statement

我有一个像下面的大开关:

public int procList(int prov, ArrayList<TXValue> txValueList, Context context)
{
    switch(prov)
    {
    case Foo.PROV_ONE:
        return proc_one(txValueList, context);

    case Foo.PROV_NOE:
        return proc_noe(txValueList, context);

    case Foo.PROV_BAR:
        return proc_bar(txValueList, context);

    case Foo.PROV_CABAR:
        return proc_cabar(txValueList, context);

    case Foo.PROV_FAR:
        return proc_far(txValueList, context);

    case Foo.PROV_TAR:
        return proc_tar(txValueList, context);

    case Foo.PROV_LBI:
        return 408;

    default:
        return -1;
    }
}
Run Code Online (Sandbox Code Playgroud)

在c ++中,我可以std::map<Foo, some_function_ptr>按照以下方式使用和使用它:

map[prov](txValueList, context); 
Run Code Online (Sandbox Code Playgroud)

Java中没有指向函数的指针.但是,它使用抽象类,就像它在答案中一样.那么,有没有一种最好的方法来消除switchjava中的大条款?

Epi*_*rce 7

你要找的是一个枚举.

public enum Prov {
    PROV_ONE(Foo.PROV_ONE) {
        @Override
        public int provMethod(List<TXValue> txValueList, Context context) {
            return proc_one(txValueList, context);
        }
    },
    PROV_NOE(Foo.PROV_NOE) {
        @Override
        public int provMethod(List<TXValue> txValueList, Context context) {
            return proc_noe(txValueList, context);
        }
    },
    PROV_BAR(Foo.PROV_BAR) {
        @Override
        public int provMethod(List<TXValue> txValueList, Context context) {
            return proc_bar(txValueList, context);
        }
    },
    PROV_CABAR(Foo.PROV_CABAR) {
        @Override
        public int provMethod(List<TXValue> txValueList, Context context) {
            return proc_cabar(txValueList, context);
        }
    },
    PROV_FAR(Foo.PROV_FAR) {
        @Override
        public int provMethod(List<TXValue> txValueList, Context context) {
            return proc_far(txValueList, context);
        }
    },
    PROV_TAR(Foo.PROV_TAR) {
        @Override
        public int provMethod(List<TXValue> txValueList, Context context) {
            return proc_tar(txValueList, context);
        }
    },
    PROV_LBI(Foo.PROV_LBI) {
        @Override
        public int provMethod(List<TXValue> txValueList, Context context) {
            return 408;
        }
    },
    UNKNOWN(Integer.MIN_VALUE) { // make sure this is not used in other IDs
                                 //decide if you actually need this
        @Override
        public int provMethod(List<TXValue> txValueList, Context context) {
            return -1;
        }            
    };

    private int id;

    private Prov(int id) {
        this.id = id;
    }

    public abstract int provMethod(List<TXValue> txValueList, Context context);

    public static Prov getById(int id) {
        for(Prov prov : Prov.values()) {
            if(id == prov.id) {
                return prov;
            }
        }
        //return null;
        //throw new IllegalArgumentException("Specified id was not found.");
        return Prov.UNKNOWN;
    }
}
Run Code Online (Sandbox Code Playgroud)

那你可以做

public int procList(int prov, ArrayList<TXValue> txValueList, Context context)
{
    return Prov.getById(prov).provMethod(txValueList, context);
}
Run Code Online (Sandbox Code Playgroud)

  • @biziclop - 一般:)但也有缺点.并且这个特定的解决方案无法在编译时确保所有`Foo.*`都被覆盖.如果我们将`Foo`改为enum,OP可能不希望将`Foo`的依赖引入其他代码. (2认同)