Java中 switch-case 如何优化?

代码样式如下:

switch(code) {
        case 1:
            //调用方法
            method1();
            break;
        case 2:
            //调用方法    
            method2();
            break;
        case 3:
            //调用方法
            method3();
            break;
        case 4:
           //调用方法
           method4();
           break;
        case 5:
            //调用方法
            method5();
            break;
        case 6:
            //调用方法
            method6();
            break;
        case 7:
            //调用方法
            method7();
            break;
        case 8:
            //调用方法
            method8();
            break;
        case 9:
            //调用方法
            method9();
            break;
        case 10:
            //调用方法
            method10();
            break;
        case 11:
            //调用方法
            method11();
            break;
        case 12:
            //调用方法
            method12();
            break;
        case 13:
            //调用方法
            method13();
            break;
        case 14:
            //调用方法
            method14();
            break;
        case 15:
            //调用方法
            method15();
            break;
        case 16:
            //调用方法
            method16();
            break;
        case 17:
            //调用方法
            method17();
            break;
        default:
            //调用方法
            methodDefalut();
            break;
}

这段switch代码已经是很整洁了,但由于条件太多,switch语句就变得很长了!而且这样写不符合开闭原则,每增加一个条件,就又要修改这段代码!可读性也会随着长度增长而变差!
所以,我想请教各位大佬,如何写一个优雅的代码来替换上面这段代码?
我有已经想到两种方法:
(1)使用容器,每个方法都换成一个类,但这样的话,就要多加 17个类!(如果能解决类的数量过多问题,就好了)
(2)使用反射,但是反射的速度太慢了,这段代码是放在一个接口里面的,性能太差会影响接口吞吐速率!
我们可以看到上面两种方法都有一些缺点,所以我想请教各位,有没有什么更好的方法?谢谢!

阅读 14.2k
3 个回答

用容器不需要每个方法斗定义类,使用函数式接口作为容器的元素即可。
用Runnable语义上可能不太合适,但JDK自带的不接受任何参数也没有返回值的函数式接口除了这个没找到别的,如有请指出

    private List<Runnable> runnableList;//Runnable在这里是作为一个函数式接口使用
    {
        List<Runnable> tmp = Stream.<Runnable>of(this::method1, this::method2, this::method3).collect(Collectors.toList());
        
        runnableList = Collections.unmodifiableList(tmp);
    }

    public void myMethod(int code) {
        Runnable runnable = runnableList.get(code);
        if (runnable == null) {
            methodDefault();
            return;
        }
        runnable.run();
    }

    private void method1() {

    }
    private void method2() {

    }
    private void method3() {

    }
    private void methodDefault() {

    }

也可以不定义method1,method2,...methodn

        List<Runnable> tmp = Stream.<Runnable>of(() -> {
                    //method1逻辑
                },
                () -> {
                    //method2逻辑
                },
                () -> {
                    //method3逻辑
                }).collect(Collectors.toList());

或者用枚举

    public void myMethod(int code) {
        MyMethod myMethod = MyMethod.values()[code];
        if (myMethod == null) {
            methodDefault();
            return;
        }
        myMethod.execute();
    }
    
    private void methodDefault() {

    }

    private enum MyMethod {
        M1(() -> {
            //method1逻辑
        }),
        M2(() -> {
            //method2逻辑
        });

        private Runnable runnable;

        MyMethod(Runnable runnable) {
            this.runnable = runnable;
        }

        public void execute() {
            runnable.run();
        }
    }

这段switch效率已经不错了,想让它变得优雅,可以考虑使用注解(@test(code))标记对应的处理函数,利用apt生成swtich代码

不需要17个类,17个function就行了

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题