枚举

作者: 爱我中华_688c | 来源:发表于2019-01-05 18:00 被阅读3次

    一。基本enum(枚举)特征

    0.创建枚举时编译器(javac 生成.class)会为我们生成一个相关的类,通过反编译该.class,我们可知道该类继承enum。查阅该enum(抽象类),enum实现了comparable 和serializable两个接口。

    1.0定义:关键字enum 。我们自己定义的枚举

    public enum Shrubbery {

    GROUNG,CRAWLING

    }

    1.1 编译器为我们生成的相关类结构。

    public final class Shrubbery extends Enum

    {

        //    public static Shrubbery[] values()

        {

            return (Shrubbery[])$VALUES.clone();

        }

        //根据实例名获取实例

        public static Shrubbery valueOf(String s)

        {

            return (Shrubbery)Enum.valueOf(Shrubbery, s);

        }

        //私有构造方法,这里调用了父类的构造方法,其中参数s对应了常量名,参数i代表枚举的一个顺序(这个顺序与枚举的声明顺序对应,用于oridinal()方法返回顺序值)    private Shrubbery(String s, int i)

        {

            super(s, i);

        }

        //我们定义的枚举在这里声明了三个 ColorEnum的常量对象引用,对象的实例化在static静态块中    public static final Shrubbery GROUNG;

        public static final Shrubbery CRAWLING;

        //将所有枚举的实例存放在数组中    private static final Shrubbery $VALUES[];

        static

        {

            GROUNG = new GROUNG("GROUNG", 0);

            CRAWLING = new CRAWLING("GROUNG", 1)

            //将所有枚举的实例存放在数组中        $VALUES = (new ColorEnum[] {

                GROUNG,CRAWLING

            });

        }

    }

    1.2我们通过分析编译器为我们生成的类和其继承结构。我们可得到一些基本用法

    1.2.1:values() 纯编译器生成可获取枚举常量数组。并且维护了我们定义时的顺序。

    1.2.2: 定义的常量引用 我们可用 == 方法(比较效率更高)

    1.2.3:分析继承结构 可用equals 和compareTo方法

    。。。。。

    二。枚举可像定义的常量一样 ,使用静态导入枚举 import static com.think.generic.enum19_1.Shrubbery.*;

    2.1 结合switch语句,不需要case enum.*  .

    三。同过向枚举中添加一些新方法,可返回对枚举的一些表述

    四。使用接口组织枚举:因为无法从enum继承子类,和编译器为我们从新定义了enum。

      如何定义枚举的分类? 》〉在一个接口的内部定义,创建实现了该接口的枚举,(定义枚举的枚举)(枚举和接口的组合)

    //分类泛型

    public interface Food {

        enum Appetizer implements Food{A1,A2,A3}

        enum MainCourse implements Food{M1,M2,M3}

        enum Coffer implements Food{C1,C2,C3}

    }

    //范型应用  需要定义构造  定义枚举的枚举

    public enum Course {

        //需要定义构造方法 The constructor Course(Class<Food.Coffer>) is undefined

        APPETIZE(Food.Appetizer.class),

        MainCourse(Food.MainCourse.class),

        Coffer(Food.Coffer.class);

        //定义返回值  枚举的枚举

        private Food[] valuses;

        //枚举的构造器返回的是泛型方法中的向上类型

        // 构造方法

        private Course(Class<? extends Food> food) {

        Food[] enumConstants = food.getEnumConstants();    

        valuses = enumConstants;

        }

        public Food randomSelectiong() {

        return EnumUtils.random(valuses);

            }

    }

    创建一个枚举对象的工具类 随机返回

    public class EnumUtils {

        private static Random random = new Random(47);

        public static <T extends Enum<T>> T random(Class<T> e) {

        T[] enumConstants = e.getEnumConstants();

        return random(enumConstants);

    }

        public static <T> T random(T[] values) {

                T t = values[random.nextInt(values.length)];

                return t;

            }

    }

    另一种返回枚举的枚举  第一个枚举(Meal)里面是{APPETIZE,MainCourse,Coffer}

    对应包含的枚举在 Food 接口中

    public enum Meal {

        APPETIZE(Food.Appetizer.class),

        MainCourse(Food.MainCourse.class),

        Coffer(Food.Coffer.class);

        private Food[] valuses;

        private Meal(Class<? extends Food> kind) {

            valuses = kind.getEnumConstants();

        }

        public interface Food {

            enum Appetizer implements Food{A1,A2,A3}

            enum MainCourse implements Food{M1,M2,M3}

            enum Coffer implements Food{C1,C2,C3}

        }

        public static void main(String[] args) {

            for (Meal m : Meal.values()) {

                System.out.println(m.name());

                for (Food food : m.valuses) {

                    System.out.println(food);

            }

            System.out.println("------------");

            }

        }

       }

    五:EnumSets是一种set集合,该集合只能存放指定枚举类型(通过泛型制定)

    public enum AlarmPoint {

            START1,START2,LOBBY,OFFICE1,OFFICE2,OFFICE3,OFFICE4,BATHROOM,U        TILITY,KITCHEN

    }

    使用案例

    public class EnumSets {

        public static void main(String[] args) {

        //定义一个空的EnumSet集合

        EnumSet<AlarmPoint> point = EnumSet.noneOf(AlarmPoint.class);

         point.add(BATHROOM);

        System.out.println(point);

        point.addAll(EnumSet.of(START1, START2, KITCHEN));

        System.out.println(point);

        point = EnumSet.allOf(AlarmPoint.class);

        System.out.println(point);

        point.remove(START1);

        System.out.println(point);

        EnumSet<AlarmPoint> complementOf = EnumSet.complementOf(point);

        System.out.println(complementOf);

        }

    }

    六:EnumMap 是一种map集合,该集合中的key只能是制定枚举类型(通过泛型制定),案例是结合命令模式的用法,一般命令模式需要一个接口,该接口内部需要一个命令方法。

    使用案例

    interface Command {void action();}

    public class EnumMaps {

        public static void main(String[] args) {

        EnumMap<AlarmPoint, Command> enumMap = new EnumMap<>(AlarmPoint.class);

        enumMap.put(KITCHEN, new Command() {

            @Override

            public void action() {

                System.out.println("厨房着火了");

            }

    });

        enumMap.put(BATHROOM, new Command() {

            @Override

            public void action() {

        System.out.println("浴室警报!!!");

        }

    });

            //Set<Entry<AlarmPoint, Command>> entrySet = enumMap.entrySet();

            for (Map.Entry<AlarmPoint, Command> entry : enumMap.entrySet()) {

           System.out.println(entry.getKey());

            entry.getValue().action();

           }

            //空指针异常

            enumMap.get(OFFICE1).action();

        }

    }

    相关文章

      网友评论

          本文标题:枚举

          本文链接:https://www.haomeiwen.com/subject/tforrqtx.html