枚举

来源:互联网 发布:abb机器人软件下载 编辑:程序博客网 时间:2024/06/05 05:12

        • 枚举简介
        • 枚举定义
        • 枚举使用
        • 静态final和枚举区别
        • 枚举类作为类的成员使用
        • 遍历枚举类的值
        • javalangEnum类说明
        • 枚举类中实例是一个对象
        • 利用接口组织枚举类
        • EnumMap
          • EnumMap小实例
        • EnumSet
          • EnumSet小例子

枚举简介

枚举值是给域或者方法创建一系列的有效值,枚举内可以单独存在,也可以在某个类中作为内部类。

枚举定义

public enum Test112 {   NUMBER ,   NUMBER1}

枚举是区分大小写,多个枚举值之间要用逗号隔开,可以写在一行或者多行。

枚举使用

private static Test112 t;    public static void main(String[] args) {        t = Test112.NUMBER;    }

使用枚举中的值就像是用静态类的静态成员一样。首先,你是需要定义这个枚举类型的变量去接收他。

静态final和枚举区别

public class Test111 {   public static final int NUMBER1 = 1;   public static final int NUMBER2 = 2;}
    private static Test112 t;    private static int t1;    public static void main(String[] args) {        t = Test112.NUMBER;        //t = 1;枚举变量只能是枚举值,不可以在赋其他值        t1 = Test111.NUMBER1;        t1 = 3;//而静态final的变量,是可以在进行赋值。    }

如果是通过枚举,枚举类型的变量只能是枚举值的其中一个,并且枚举变量不可以赋其他值。而静态final是可以实现类似枚举的预定义值,但是接收静态final的变量,你注意看,还是根据他的值的基本类型去划分,所以你可以用同种类型值给他赋值。另外,枚举值是一个对象,因此它的行为和对象一样。

枚举类作为类的成员使用

public class Test111 {   private enum type{NUMBER,NUMBER1};   type t = type.NUMBER;}

遍历枚举类的值

     for(<枚举类> t:<枚举类>.values()) {        System.out.println(t.toString());    }

java.lang.Enum类说明

  1. 没有公开的构造器,也就是说程序员不能构造实例。 其实很容易想明白,所谓枚举类就是有包含有固定数量实例(并且实例的值也固定)的特殊类,如果其含有public构造器,那么在类的外部就可以通过这个构造器来新建实例,显然这时实例的数量和值就不固定了,这与定义枚举类的初衷相矛盾
  2. 枚举类的每一个实例都是隐式静态,这也就解释了为啥每次调用都是<枚举类>.直接调用。
  3. 每一个枚举变量只有一个实例。
  4. ordinal()返回枚举常量的序数(它在枚举声明中的位置,其中初始常量序数为零)。这个和后面的EnumMap有关。
  5. 记住,枚举类不可以继承任何类,因为他们只继承 java.lang.Enum,java是单继承。

枚举类中实例是一个对象

当我们枚举中对的实例不是一个简单字段的时候,或者是你定义的字符串的时候,那么这个时候,实例可以是个对象,而这时,一切可以应用到对象上的,都可以用在实例中。

package com.example.test;public enum Test112 {     number(0,"我是实例0的值"),     number1(1,"我是实例1的值"),     number2(2,"我是实例2的值"),     number3(3,"我是实例3的值");//首先申明了4个实例,我们number(0,"我是实例0的值")看做是一个构造函数,只是类比记忆,那么需要提供一个构造函数是吧(注意虽然构造函数是写在枚举类中,但是不是枚举类的,枚举类没有构造函数,已经强调几遍了),这里的构造函数,只是写在这边以保证实例不会编译出错,在后面测试,你会发现,其实你又不能用这个构造没有意义,但是必须写在这,很多时候,没有那么多为什么!!!!并且这指明这两个参数的字段名。    private int num ;    private String name1;    public String getName1() {        return name1;    }    public void setName1(String name1) {        this.name1 = name1;    }    private Test112(int num, String name1) {        this.num = num;        this.name1 = name1;    }    public int getNum() {//暴露出每个属性的get、set方便之后的修改。        return num;    }    public void setNum(int num) {        this.num = num;    }}

注意:

如果打算自定义自己的方法,那么必须在enum实例序列的最后添加一个分号。而且 Java 要求必须先定义 enum 实例。

//参考学习https://www.cnblogs.com/happyPawpaw/archive/2013/04/09/3009553.html

测试:

    Test112 t2 = Test112.number1;        t2.setNum(5);//通过暴露出的方法,修改值        t2.setName1("我是修改的");        Test112[] t = Test112.values();//values()方法获取每一个实例对象        for(Test112 tt:t) {            System.out.println(tt.getNum()+"*****"+tt.getName1());//            //遍历,通过暴露出的方法,获取实例对应属性的值        }

利用接口组织枚举类

//参考学习https://www.cnblogs.com/happyPawpaw/archive/2013/04/09/3009553.html

    public interface Test115 {        enum Coffee implements Test115 {            BLACK_COFFEE, DECAF_COFFEE, LATTE, CAPPUCCINO        }        enum Dessert implements Test115 {            FRUIT, CAKE, GELATO        }    }

使用:

    Test115 t = Test115.Coffee.BLACK_COFFEE;    Test115 t1 = Test115.Dessert.FRUIT;}

通过这个方法,我们可以将多个不同枚举类组织在一起使用。

EnumMap

该类是将Map和Enum的结合使用,将Enum类型的实例,作为Map的键。

由 iterator 方法返回的迭代器按其自然顺序 遍历这些元素(该顺序是声明枚举常量的顺序)

EnumMap小实例
   Map<Test112,String> map = new EnumMap<Test112,String>(Test112.class);               //map.put("1","我是枚举map1");根据泛型,这个是不能添加,我们这里规定键是指定枚举类中的实例              map.put(Test112.number1,"sdasa11");              //map.put(null,"sdsada222");              //不允许使用 null 键。试图插入 null 键将抛出 Null              //PointerException。但是,试图测试是否出现 null 键或              //移除 null 键将不会抛出异常。允许使用 null 值。              map.put(Test112.number2,"sdasa33");              map.put(Test112.number3,"sdasa44");             Set<Entry<Test112,String>> s =map.entrySet();//这个方法是获取map中所有映射关系的集合             for(Entry<Test112, String> entry:s) {//遍历所有映射关系                 System.out.println(entry.getKey()+"^^^^"+entry.getValue());//拿到每个映射对应的名和值             }             String value = map.get(Test112.number1);             System.out.println(value);             //其原理就是一个对象数组,数组的下标索引就是根据Map中的key             //直接获取,即枚举中的ordinal值;             //效率比HashMap高,可以直接获取数组下标索引并访问到元素;//参考学习https://www.cnblogs.com/chenpi/archive/2016/03/19/5296330.html             /* 源码   public V get(Object key) {                    return (isValidKey(key) ?                            unmaskNull(vals[((Enum<?>)key).ordinal()]) : null);                }*/

EnumSet

其实就是Set和Enum结合使用,set中的元素都是枚举类的,我们先回忆一下Set,是一个集合,在这个集合中,会自动去除重复元素,并且允许空值,最多一个,不能重复呀。

EnumSet小例子
  Set<Test112> s  = new HashSet<>();   s.add(Test112.number);   s.add(Test112.number1);   s.add(Test112.number2);   Iterator i = s.iterator();    while(i.hasNext()) {        System.out.println(i.next());    }