• 枚举


    枚举

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

    复制代码
    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都是线程非安全的。

  • 相关阅读:
    K
    A
    2017 Multi-University Training Contest
    第一章 概述
    校赛F 比比谁更快(线段树)
    POJ 3683 Priest John's Busiest Day
    POJ 2186 Popular Cows
    第十五周讨论
    线段树模板(单点更新,区间更新,RMQ)
    2-SAT问题(白书)
  • 原文地址:https://www.cnblogs.com/szlbm/p/5504700.html
Copyright © 2020-2023  润新知