zoukankan      html  css  js  c++  java
  • 枚举

    Java声明枚举类型、枚举(enum)类、EnumMap 与 EnumSet

    枚举是一个被命名的整型常数的集合,用于声明一组带标识符的常数

    在 JDK 1.5 之前没有枚举类型,那时候一般用接口常量来替代。而使用 Java 枚举类型 enum 可以更贴近地表示这种常量。

    声明枚举

    枚举的修饰符主要包括 public、private 和 internal


    任意两个枚举成员不能具有相同的名称,且它的常数值必须在该枚举的基础类型的范围之内,多个枚举成员之间使用逗号分隔。

    提示:如果没有显式地声明基础类型的枚举,那么意味着它所对应的基础类型是 int。

    例 1

    下面代码定义了一个表示性别的枚举类型 SexEnum 和一个表示颜色的枚举类型 Color。

    1. public enum SexEnum {
    2. male,female;
    3. }
    4. public enum Color {
    5. RED,BLUE,GREEN,BLACK;
    6. }

    例2:

    1. enum Signal {
    2. // 定义一个枚举类型
    3. GREEN,YELLOW,RED
    4. }
    5. public class TrafficLight {
    6. Signal color = Signal.RED;
    7. public void change() {
    8. switch(color) {
    9. case RED:
    10. color = Signal.GREEN;
    11. break;
    12. case YELLOW:
    13. color = Signal.RED;
    14. break;
    15. case GREEN:
    16. color = Signal.YELLOW;
    17. break;
    18. }
    19. }
    20. }

    枚举类

    Java 中的每一个枚举都继承自 java.lang.Enum 类

    Enum 类的实例,这些枚举成员默认都被 final、public, static 修饰,当使用枚举类型成员时,直接使用枚举名称调用成员即可。

    例 2

    通过调用枚举类型实例的 values( ) 方法可以将枚举的所有成员以数组形式返回,也可以通过该方法获取枚举类型的成员。

    下面的示例创建一个包含 3 个成员的枚举类型 Signal,然后调用 values() 方法输出这些成员。

    1. enum Signal {
    2. // 定义一个枚举类型
    3. GREEN,YELLOW,RED;
    4. }
    5. public static void main(String[] args) {
    6. for(int i = 0;i < Signal.values().length;i++) {
    7. System.out.println("枚举成员:"+Signal.values()[i]);
    8. }
    9. }

    例 3

    创建一个示例,调用valueOf() 方法获取枚举的一个成员,再调用 compareTo() 方法进行比较,并输出结果。具体实现代码如下:

    1. public class TestEnum {
    2. public enum Sex {
    3. // 定义一个枚举
    4. male,female;
    5. }
    6. public static void main(String[] args) {
    7. compare(Sex.valueOf("male")); // 比较
    8. }
    9. public static void compare(Sex s) {
    10. for(int i = 0;i < Sex.values().length;i++) {
    11. System.out.println(s + "与" + Sex.values()[i] + "的比较结果是:" + s.compareTo(Sex.values()[i]));
    12. }
    13. }
    14. }

    例 4

    通过调用枚举类型实例的ordinal() 方法可以获取一个成员在枚举中的索引位置。下面的示例创建一个包含 3 个成员的枚举类型 Signal,然后调用 ordinal() 方法输出成员及对应索引位置。

    1. public class TestEnum1 {
    2. enum Signal {
    3. // 定义一个枚举类型
    4. GREEN,YELLOW,RED;
    5. }
    6. public static void main(String[] args) {
    7. for(int i = 0;i < Signal.values().length;i++) {
    8. System.out.println("索引" + Signal.values()[i].ordinal()+",值:" + Signal.values()[i]);
    9. }
    10. }
    11. }

    为枚举添加方法

    例 5

    下面的代码创建了一个枚举类型 WeekDay,而且在该类型中添加了自定义的方法。

    1. enum WeekDay {
    2. Mon("Monday"),Tue("Tuesday"),Wed("Wednesday"),Thu("Thursday"),Fri("Friday"),Sat("Saturday"),Sun("Sunday");
    3. // 以上是枚举的成员,必须先定义,而且使用分号结束
    4. private final String day;
    5. private WeekDay(String day) {
    6. this.day = day;
    7. }
    8. public static void printDay(int i) {
    9. switch(i) {
    10. case 1:
    11. System.out.println(WeekDay.Mon);
    12. break;
    13. case 2:
    14. System.out.println(WeekDay.Tue);
    15. break;
    16. case 3:
    17. System.out.println(WeekDay.Wed);
    18. break;
    19. case 4:
    20. System.out.println(WeekDay.Thu);
    21. break;
    22. case 5:
    23. System.out.println(WeekDay.Fri);
    24. break;
    25. case 6:
    26. System.out.println(WeekDay.Sat);
    27. break;
    28. case 7:
    29. System.out.println(WeekDay.Sun);
    30. break;
    31. default:
    32. System.out.println("wrong number!");
    33. }
    34. }
    35. public String getDay() {
    36. return day;
    37. }
    38. }
    1. public static void main(String[] args) {
    2. for(WeekDay day : WeekDay.values()) {
    3. System.out.println(day+"====>" + day.getDay());
    4. }
    5. WeekDay.printDay(5);
    6. }

    Java 中的 enum 还可以跟 Class 类一样覆盖基类的方法。下面示例代码创建的 Color 枚举类型覆盖了 toString() 方法。

    1. public class Test {
    2. public enum Color {
    3. RED("红色",1),GREEN("绿色",2),WHITE("白色",3),YELLOW("黄色",4);
    4. // 成员变量
    5. private String name;
    6. private int index;
    7. // 构造方法
    8. private Color(String name,int index) {
    9. this.name = name;
    10. this.index = index;
    11. }
    12. // 覆盖方法
    13. @Override
    14. public String toString() {
    15. return this.index + "-" + this.name;
    16. }
    17. }
    18. public static void main(String[] args) {
    19. System.out.println(Color.RED.toString()); // 输出:1-红色
    20. }
    21. }

    EnumMap(为map自定) 与 EnumSet(实现List)

    为了更好地支持枚举类型,java.util 中添加了两个新类:EnumMap 和 EnumSet。使用它们可以更高效地操作枚举类型。

    EnumMap 类

    EnumMap 是专门为枚举类型量身定做的 Map 实现。虽然使用其他的 Map(如 HashMap)实现也能完成枚举类型实例到值的映射,但是使用 EnumMap 会更加高效。

    HashMap 只能接收同一枚举类型的实例作为键值,并且由于枚举类型实例的数量相对固定并且有限,所以 EnumMap 使用数组来存放与枚举类型对应的值,使得 EnumMap 的效率非常高。

    例 6

    下面是使用 EnumMap 的一个代码示例。枚举类型 DataBaseType 里存放了现在支持的所有数据库类型。针对不同的数据库,一些数据库相关的方法需要返回不一样的值,例如示例中 getURL() 方法。

    1. // 定义数据库类型枚举
    2. public enum DataBaseType {
    3. MYSQUORACLE,DB2,SQLSERVER
    4. }
    5. // 某类中定义的获取数据库URL的方法以及EnumMap的声明
    6. private EnumMap<DataBaseType,String>urls = new EnumMap<DataBaseType,String>(DataBaseType.class);
    7. public DataBaseInfo() {
    8. urls.put(DataBaseType.DB2,"jdbc:db2://localhost:5000/sample");
    9. urls.put(DataBaseType.MYSQL,"jdbc:mysql://localhost/mydb");
    10. urls.put(DataBaseType.ORACLE,"jdbc:oracle:thin:@localhost:1521:sample");
    11. urls.put(DataBaseType.SQLSERVER,"jdbc:microsoft:sqlserver://sql:1433;Database=mydb");
    12. }
    13. //根据不同的数据库类型,返回对应的URL
    14. // @param type DataBaseType 枚举类新实例
    15. // @return
    16. public String getURL(DataBaseType type) {
    17. return this.urls.get(type);
    18. }

    在实际使用中,EnumMap 对象 urls 往往是由外部负责整个应用初始化的代码来填充的。这里为了演示方便,类自己做了内容填充。

    从本例中可以看出,使用 EnumMap 可以很方便地为枚举类型在不同的环境中绑定到不同的值上。本例子中 getURL 绑定到 URL 上,在其他的代码中可能又被绑定到数据库驱动上去。

    EnumSet 类

    EnumSet 是枚举类型的高性能 Set 实现,它要求放入它的枚举常量必须属于同一枚举类型。EnumSet 提供了许多工厂方法以便于初始化,如表 2 所示。

    EnumSet 作为 Set 接口实现,它支持对包含的枚举常量的遍历。

     

    1. for(Operation op:EnumSet.range(Operation.PLUS,Operation.MULTIPLY)) {
    2. doSomeThing(op);
    3. }
  • 相关阅读:
    U盘备份工具
    改进的窗口置顶工具
    有关DLL中封装的MDI子窗体出现TFont错误的解释
    QQ风格程序的编写
    改进的自动按键工具
    万能Update语句
    在DLL中封装的VCL窗体Tab键响应的问题
    自动按键工具
    灵活控制SVN服务
    在DLL动态链接库中封装VCL的MDI子窗体
  • 原文地址:https://www.cnblogs.com/lkwcrystal/p/12447537.html
Copyright © 2011-2022 走看看