zoukankan      html  css  js  c++  java
  • 枚举

    枚举

    枚举是一个小功能,但是却带来了大方便。一个星期有七天,我们平时定义这七天为常量的时候,会这么写:

    复制代码
    public final static String SUNDAY = "0";
    public final static String MONDAY = "1";
    public final static String TUESDAY = "2";
    public final static String WEDNESDAY = "3";
    public final static String THRUSDAY = "4";
    public final static String FRIDAY = "5";
    public final static String SATURDAY = "6";
    复制代码

    有了枚举之后,就可以换一种写法了:

    public enum EnumDay
    {
        SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THRUSDAY, FRIDAY, SATURDAY;
    }

    这就定义了SUNDAY~SATURDAY的枚举了,使用枚举类型代替了常量,还提供了比常量更多的方法。枚举类型适用的数据有以下特点:

    1、枚举值之间是有内在关联的,比如上面的,都是一个星期的七天

    2、常量的值是随便的,比如SUNDAY必须是"12345",MONDAY必须是"23456"也可以用枚举,不过要麻烦些

    上面的EnumDay其实隐含了所创建的类型都是java.lang.Enum类的子类,枚举类型符合通用模式Class Enum<E extends Enum<E>>,E表示的就是枚举类型的名称。枚举类型的每一个值都将映射到protected Enum<String name, int ordinal>构造函数中,在这里,每个值的名称都被转换为一个字符串,并且序数设置表示了此设置被创建的顺序。EnumDay实际调用了7此Enum:

    复制代码
    new Enum<EnumDay>("SUNDAY", 0);
    new Enum<EnumDay>("MONDAY", 1);
    new Enum<EnumDay>("TUESDAY", 2);
    new Enum<EnumDay>("WEDNESDAY", 3);
    new Enum<EnumDay>("THRUSDAY", 4);
    new Enum<EnumDay>("FRIDAY", 5);
    new Enum<EnumDay>("SATURDAY", 6);
    复制代码

    所以,只要记住每个枚举值都是一个泛型为EnumDay的Enum就可以了。

    遍历枚举类型及枚举方法

    既然知道了枚举类型里面的枚举值都是一个Enum<EnumDay>,那就好办了,可以查看JDK API来看下Enum里面有哪些方法并使用下,看一下例子:

    复制代码
    public static void main(String[] args) throws Exception
    {
        EnumDay[] eds = EnumDay.values(); // 将EnumDay中的枚举值转换为EnumDay数组
        int i = 0;
        for (EnumDay ed : eds)
        {
            System.out.println("EnumDay[" + i + "]:" + ed.toString()); // 返回枚举常量的名称
            i++;
        }
        System.out.println();
            
        System.out.println("Enum<EnumDay>.compareTo():" + eds[0].compareTo(eds[1])); // 比较此枚举与指定枚举的顺序,被比较对象小于、等于、大于比较对象时,分别返回负整数、0、正整数,只能和相同枚举类型相比较
        System.out.println("Enum<EnumDay>.equals():" + eds[0].equals(eds[1])); // 比较指定两个枚举类型是否相同
        System.out.println("Enum<EnumDay>.getDeclaringClass():" + eds[0].getDeclaringClass()); // 获取指定枚举值的枚举类型对应的Class对象
        System.out.println("Enum<EnumDay>.hashCode():" + eds[0].hashCode()); // 获取指定枚举值对应的hashCode
        System.out.println("Enum<EnumDay>.name():" + eds[0].name()); // 获取指定枚举值的名称
        System.out.println("Enum<EnumDay>.ordinal():" + eds[0].ordinal()); // 获取指定枚举值对应的序数
    }
    复制代码

    结果为:

    复制代码
    EnumDay[0]:SUNDAY
    EnumDay[1]:MONDAY
    EnumDay[2]:TUESDAY
    EnumDay[3]:WEDNESDAY
    EnumDay[4]:THRUSDAY
    EnumDay[5]:FRIDAY
    EnumDay[6]:SATURDAY
    
    Enum<EnumDay>.compareTo():-1
    Enum<EnumDay>.equals():false
    Enum<EnumDay>.getDeclaringClass():class com.xrq.test37.EnumDay
    Enum<EnumDay>.hashCode():1414159026
    Enum<EnumDay>.name():SUNDAY
    Enum<EnumDay>.ordinal():0
    复制代码

    看到toString()方法和name()方法的值是一样,可能有人会想,那要这两个方法干嘛?toString()方法这里因为没有重写,实际上这个方法被开发者重写之后,就打印出了开发者需要的内容了,没有重写toString()方法打印的就是name属性了,看一下Enum类的源代码就知道了。

    为枚举类型中的枚举值定义数值----自定义属性和方法

    不给枚举类型中的枚举值定义数值,那么数值是从0开始逐个加上去的,当然我们也可以给枚举类型中的枚举值自定义数值,这时就要在EnumDay里面自定义属性和方法了:

    复制代码
    public enum EnumDay
    {
        SUNDAY(1234), MONDAY(2345), TUESDAY(3456), WEDNESDAY(4567), THRUSDAY(5678), FRIDAY(6789), SATURDAY(7890)
        {
            public String toString()
            {
                return super.toString();
            }
        };
        
        private int value;
        
        private EnumDay(int value)
        {
            this.value = value;
        }
        
        public int getValue()
        {
            return value;
        }
    }
    复制代码

    main函数可以直接调用getValue()方法,因为每个枚举值都是一个EnumDay:

    复制代码
    public static void main(String[] args)
    {
        EnumDay[] eds = EnumDay.values();
        for (EnumDay ed : eds)
        {
            System.out.println(ed.name() + ":" + ed.getValue());
        }
    }
    复制代码

    运行结果为:

    复制代码
    SUNDAY:1234
    MONDAY:2345
    TUESDAY:3456
    WEDNESDAY:4567
    THRUSDAY:5678
    FRIDAY:6789
    SATURDAY:7890
    复制代码

    从例子中看到,可以为枚举类型自定义方法,也可以自定义属性,也可以重写父类中的方法(如果不自定义方法的话,只有toString()方法可以重写,因为只有它不是final的),枚举类型是Enum<E extends Enum<E>>,所以EnumDay也可以继承类,实现接口,定义更多的方法。

    EnumSet、EnumMap

    EnumSet和EnumMap是分别为枚举类型定制的Set和Map,看一下它们的用法:

    复制代码
    public static void main(String[] args)
    {
        EnumSet<EnumDay> es = EnumSet.allOf(EnumDay.class);
        for (EnumDay ed : es)
            System.out.println(ed.name() + ":" + ed.ordinal());
            
        System.out.println("
    -----EnumSet和EnumMap之间的分隔线-----
    ");
            
        EnumMap<EnumDay, String> em = new EnumMap<EnumDay, String>(EnumDay.class);
        em.put(EnumDay.SUNDAY, "星期天");
        em.put(EnumDay.MONDAY, "星期一");
        em.put(EnumDay.TUESDAY, "星期二");
        em.put(EnumDay.WEDNESDAY, "星期三");
        em.put(EnumDay.THRUSDAY, "星期四");
        em.put(EnumDay.FRIDAY, "星期五");
        em.put(EnumDay.SATURDAY, "星期六");
            
        Iterator<Entry<EnumDay, String>> iterator = em.entrySet().iterator();
        while (iterator.hasNext())
        {
            Entry<EnumDay, String> entry = iterator.next();
            System.out.println(entry.getKey().name() + ":" + entry.getValue());
        }
    }
    复制代码

    运行结果为:

    复制代码
    SUNDAY:0
    MONDAY:1
    TUESDAY:2
    WEDNESDAY:3
    THRUSDAY:4
    FRIDAY:5
    SATURDAY:6
    
    -----EnumSet和EnumMap之间的分隔线-----
    
    SUNDAY:星期天
    MONDAY:星期一
    TUESDAY:星期二
    WEDNESDAY:星期三
    THRUSDAY:星期四
    FRIDAY:星期五
    SATURDAY:星期六
    复制代码

    注意一下EnumSet和EnumMap都是线程非安全的。

    转载:http://www.cnblogs.com/xrq730/p/4890313.html

  • 相关阅读:
    洛谷 P1194 飞扬的小鸟 题解
    洛谷 P1197 星球大战 题解
    洛谷 P1879 玉米田Corn Fields 题解
    洛谷 P2796 Facer的程序 题解
    洛谷 P2398 GCD SUM 题解
    洛谷 P2051 中国象棋 题解
    洛谷 P1472 奶牛家谱 Cow Pedigrees 题解
    洛谷 P1004 方格取数 题解
    洛谷 P2331 最大子矩阵 题解
    洛谷 P1073 最优贸易 题解
  • 原文地址:https://www.cnblogs.com/haitaofeiyang/p/7718458.html
Copyright © 2011-2022 走看看