How to condense large switch statements

时间:2015-06-15 15:08:33

标签: java switch-statement

I have a large switch like following:

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;
    }
}

In c++ I can use std::map<Foo, some_function_ptr> and use it in manner as following:

map[prov](txValueList, context); 

There is not pointer to function in Java. However, it uses abstract classes like it is in the answer. So, is there a best way to eliminate huge switch clauses in java?

2 个答案:

答案 0 :(得分: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;
    }
}

然后你可以做

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

答案 1 :(得分:3)

回答OP的问题,因为它是框架 -

Map<Integer, BiFunction<ArrayList<TXValue>,Context, Integer>> map = new HashMap<>();
{
    map.put(Foo.PROV_ONE, this::proc_one);
    // etc ....
    map.put(Foo.PROV_LBI, (x,y)->408 );
}

public int procList(int prov, ArrayList<TXValue> txValueList, Context context)
{
    if( ! map.contains(prov)) return -1;

    return map.get(prov).apply(txValueList, context);
}