前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java之花样玩枚举

Java之花样玩枚举

作者头像
sowhat1412
发布2020-11-05 12:13:46
3110
发布2020-11-05 12:13:46
举报
文章被收录于专栏:sowhat1412

一,枚举的引出

设定一个场景,业务需要我们的一个进件有若干状态,怎么表示这些状态呢?大部分可能会直接用static final 表示一个int类型的变量。如下:

代码语言:javascript
复制
    //订单状态
    public static final int ORDER_DEPOT_UNPAY = 0;
    public static final int ORDER_DEPOT_PAID = 1;
    public static final int ORDER_DEPOT_TIMOUT = 2;

然后接下来的业务逻辑就是用这些常量值来带指各种基本业务含义。但是这样的弊端也有如下

  1. 它只是一个int类型的数据而已,如果我们定义了别的变量然后数字跟他一样怎么办?比如
代码语言:javascript
复制
    public static final int ORDER_LOGISTICS_READY = 0;
    public static final int ORDER_LOGISTICS_TRANSPORT = 1;
    public static final int ORDER_LOGISTICS_ARRIVED = 2;

我想用上面三个状态的一个类型,而错误的输入称了下面的一个类型怎么办?,因为在业务实现上他们最终展示的都是一个数字,还TM一样!。

  1. 这些变量我们只是一个编号,获得编号后如果我想知道具体含义怎么办?你还要构造一个编号跟含义的映射表。
  2. 这些常量是static final类型的啊,在类加载的时候,如果有些地方使用了这样常量,在类加载的间接引用会直接编程常量引用的!

这个时候用枚举更好一些。

代码语言:javascript
复制
    public enum Depot {UNPAY, PAID, TIMOUT}//0,1,2
    public enum Logistics {READY, TRANSPORT, ARRIVED}// 0,1,2

然后调用的时候如果需要值可以直接这样调用(枚举类会自动给实例编号默认从0开始)

代码语言:javascript
复制
    public static void main(String[] args) {

        System.out.println(Depot.UNPAY);
        System.out.println(Depot.UNPAY.ordinal());
    }

二,枚举进阶

但是如果这时候我们将他们的具体序号变换了咋吧?比如

代码语言:javascript
复制
    //订单状态
    public static final int ORDER_DEPOT_UNPAY = 0;
    public static final int ORDER_DEPOT_PAID = 3; //值变化了 
    public static final int ORDER_DEPOT_TIMOUT = 2;
我们可以对枚举类进行丰富化操作,使用的前提是要知道枚举类里类型一定是这个类的若干实例。其余的操作跟类和对象操作没有任何区别!。demo如下

public enum DepotEnum {
    UNPAY(0, "未支付"), PAID(1, "已支付"), TIMOUT(-1, "超时");

    private int status; //状态
    private String desc; // 含义描述
    private String dbInfo;//其他属性

    private DepotEnum(int status, String desc) {
        this.status = status;
        this.desc = desc;
    }

    public int getStatus() {
        return status;
    }

    public String getDesc() {
        return desc;
    }

    public String getDbInfo() {
        return dbInfo;
    }

    public int calcStatus(int params) {
        return status + params;
    }

    public static void main(String[] args) {
        for (DepotEnum e : DepotEnum.values()) {
            System.out.println(e + ":" + e.calcStatus(14));
        }
    }
    
}

三,再进阶

在枚举中如果我们的若干状态要跟一些行绑定在一起怎么办?JDM提供了枚举类型也可用在switch中,比如我们的加减乘除。我们可以在里面实现这样的switch 功能。

代码语言:javascript
复制
public class ActiveEnum {
 
 public enum NormalActive{
  PLUS,MINUS,MULTI,DIVIDS;
  
  double oper(double x,double y) {
   switch(this) {
   case PLUS:return x+y;
   case MINUS:return x-y;
   case MULTI:return x*y;
   case DIVIDS:return x/y;
   }
   throw new UnsupportedOperationException(); // 这个存在的含义仅仅是替换 default
  }  
 }

 public static void main(String[] args) {
  System.out.println(NormalActive.PLUS.oper(0.1, 0.2));
 }
}

那可能有的时候我们需要新添加功能了比如新添加一个微分(DIFFER)功能 咋办,我是不是要添加枚举类型,添加switch语句。

这个时候我们可以再对代码进行优化(时刻谨记枚举类型是类对实例)。

代码语言:javascript
复制
public class ActiveEnum {

 public enum BetterActive{
  PLUS {
   @Override
   double oper(double x, double y) {
    return x+y;
   }
  },MINUS {
   @Override
   double oper(double x, double y) {
    return x-y;
   }
  };
  
  abstract double oper(double x,double y); // 抽象类的引入
   
 }
 public static void main(String[] args) {
  System.out.println(NormalActive.PLUS.oper(0.1, 0.2));
 }
}

四,策略枚举引入

比如我们现在要算员工加班费,规则算工作日加班2倍工资,节假日加班3倍工资。

代码语言:javascript
复制
/**
 *@author sowhat
 *类说明:加班费计算,工作日加班2倍,节假日3倍
 */
enum PayDay {
 MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY;
 
 private static final int HOURS_WORK = 2;
 private static final int HOURS_REST = 3;
 
 //超时时间
 double pay(double hoursOvertime) {
  switch(this) {
  case SATURDAY:case SUNDAY:
   return hoursOvertime*HOURS_REST;
  default:
   return hoursOvertime*HOURS_WORK;
  }
 }
}

但是这个时候我如果要添加一个51节日的呢?我们可以考虑引入策略枚举。然后用外部枚举来包装策略枚举。

代码语言:javascript
复制
public enum BetterPayDay {
 MONDAY(PayType.WORK), TUESDAY(PayType.WORK), WEDNESDAY(
   PayType.WORK), THURSDAY(PayType.WORK), FRIDAY(PayType.WORK), 
 SATURDAY(PayType.REST), SUNDAY(PayType.REST),WUYI(PayType.REST);

 private final PayType payType; // 成员变量 然后定义一个外部枚举来包装 策略枚举。

 BetterPayDay(PayType payType) {
  this.payType = payType;
 }

 double pay(double hoursOvertime) {
  return payType.pay(hoursOvertime);
 }

 //策略枚举 我们只定义 工作日还是节假日的薪资计算方法。
 private enum PayType {
  WORK {
   double pay(double hoursOvertime) {
    return hoursOvertime*HOURS_WORK;
   }
  },
  REST {
   double pay(double hoursOvertime) {
    return hoursOvertime*HOURS_REST;
   }
  };
  private static final int HOURS_WORK = 2;
  private static final int HOURS_REST = 3;

  abstract double pay(double hoursOvertime);//抽象计算加班费的方法
 }
 
 public static void main(String[] args) {

  System.out.println(BetterPayDay.MONDAY.pay(7.5));
 }
}
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-07-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 sowhat1412 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一,枚举的引出
  • 二,枚举进阶
  • 三,再进阶
  • 四,策略枚举引入
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档