判断逻辑过多替换if-else的解决方法

510 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

引言

开发一个系统往往涉及到很多的状态,比如登录状态,在数据库中一般存储的是数字或字母,但是显示在前端的时候需要中文或英文,一般用到if-else代码判断,例如:假设状态对应关系:1:online 2:overtime 3:offline。再比如说就职状态:1.Busy、 2.Free、 3.Vocation、 4.Dimission等等,我们拿登录状态举例,代码如下:

int status;
String statusStr = null;
if (status == 1) {
   status = "online";
} else if (status == 2) {
   status = "overtime";
}else if(status == 3) {
    status = "offline";
}

但是这种判断会有一些问题,比如可读性比较差,也会影响后期维护,也比较容易出现bug。这里给出几种替代方法。

使用数组替代

这种仅限通过数字获取到字母或者中文。代码如下:

//首先设置数组,第1个留空使其index从1开始方便契合业务逻辑
String[] statusArray = {"","online","overtime","offline"};
//获取登录状态
int status = getLogOnStatus(); 
//直接通过数组转换为英文状态
String statusStr =  statusArray[status];

该方法优点就是占用内存少,可读性好,代码量小,美观。缺点也有,比如状态值只能是数字,而且还需要考虑数组越界的情况。

使用switch替代

switch很多人第一时间就能想到,实现起来也很简单,多一种情况就多写一个case就行,代码如下:

 switch(status) {
      case 1:
          statusStr = online;
          break;
      case 2:
          statusStr = overtime;
          break;
      case 3:
          statusStr = offline;
          break;
      default:
          statusStr = null;
      
}

switch语句进行条件判断后执行到程序的条件语句,效率更高。而if…else语句有几种条件,就得判断多少次。 当分支比较多时,switch语句执行效率高,而且结构更清晰。不过当分支比较少时,if…else语句执行效率高。

使用HashMap替代

我们先创建和添加map,代码如下:

private static final Map<Integer,String> map = new HashMap<>();

    static {
        map.put(1,"online");
        map.put(2,"overtime");
        map.put(3,"offline");
    }

这种有两种求解方式,通过 key 获取 value 以及通过 value 获取 key。如果是由 key 获取 value,直接使用 get 方法即可。这里的key相对于数组解法,不限制 key 的类型。如果是由 value 获取 key,就需要使用map遍历,代码如下:

//获取登录状态
int status = getLogOnStatus();
//直接通过key获取对应的英文状态
map.get(status);
//value获取key,需要遍历
for(Map.Entry<Integer, String> vo : map.entrySet()){
     if (vo.getValue().equals(status)) {
           status = vo.getKey();
           break;
      }
}

该方法的优点就是,状态值不限制数字;缺点就是占用空间大。

使用枚举替代

我们先定义一个枚举类,代码如下:

public enum TestEum {

    ONLINE(1,"agree"),
    OVERTIME(2,"refuse");

    private int code;

    private String capation;

    TestEum(int code,String capation){
        this.code = code;
        this.capation = capation;
    }

    public int getCode() {
        return code;
    }

   public String getCapation() {
        return capation;
   }
  
   String of(int code){
        for (TestEum testEum : TestEum.values()) {
            if (testEum.getCode() == code) {
                return testEum.getCapation();
            }
        }
        return null;
    } 
}

有了枚举以后,if-else 代码块可以优化成一行代码,如下:

String statusStr = TestEum.of(status);

需要注意的是,在枚举类中直接列出常量,常量遵循全部大写的规则。枚举成员默认是final、public、static修饰。枚举类是final的,所以不能继承。

如果通过数字获取描述,推荐使用数组方法来替代if-else。如果通过描述获取数字,使用枚举和HashMap都可以。不过枚举类往往还是需要switch或循环的配合,倒不如使用Map更加方便和简洁,同样效率上会类好于枚举。