JavaSE基础:枚举类型

枚举类型(Enum)

在C语言中存在一个枚举类型,经过此类型能够限制一个内容的取值范围,可是在JDK1.5以前,Java中并并不存在枚举的类型,因此不少之间已经习惯了使用枚举类型操做的开发人员就感受很不适应,为了解决这个问题(或者说吸引部分客户),因此在JDK1.5以后就加入了枚举类型。java

我我的而言,自己就是从Java学起,实际上是否使用枚举类型看本身的习惯就能够,对于我来讲有的时候枚举类型就有点鸡肋的感受,我可使用别的方式实现相似的枚举。数组

情景模式说明,咱们平时可能要获取星期几,可是咱们获取的是数组1-7的形式,那么咱们就须要对起进行处理,实现代码以下。ide

1.简单程序实现枚举功能

请注意关键的问题,咱们须要限制取值的范围!函数

package com.shxt.demo01;

public class Week {
    //定义七个星期的对象
    public static final Week SUNDAY = new Week("星期日");
    public static final Week MONDAY = new Week("星期一");
    public static final Week TUESDAY = new Week("星期二");
    public static final Week WEDNESDAY = new Week("星期三");
    public static final Week THURSDAY = new Week("星期四");
    public static final Week FRIDAY = new Week("星期五");
    public static final Week SATURDAY = new Week("星期六");

    private String date;

    //请注意这里使用的私有构造函数,没法在外部进行实例化操做
    private Week(String date){
        this.date = date;
    }

    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    //获取日期数组,从固定的星期中获取数据
    public static Week getInstance(int week){
        switch (week){
            case 1:
                return SUNDAY;
            case 2:
                return MONDAY;
            case 3:
                return TUESDAY;
            case 4:
                return WEDNESDAY;
            case 5:
                return THURSDAY;
            case 6:
                return FRIDAY;
            case 7:
                return SATURDAY;
            default:
                return null;//错误的数值

        }
    }
}

复制代码

测试代码:测试

package com.shxt.demo01;

import java.util.Calendar;

public class WeekTest {
    public static void main(String[] args) {
        Calendar calendar = Calendar.getInstance();
        //System.out.println(calendar.get(Calendar.DAY_OF_WEEK));
        Week week = Week.getInstance(calendar.get(Calendar.DAY_OF_WEEK));
        if (week!=null){
            System.out.println(week.getDate());
        }
    }
}
复制代码

代码说明:this

以上程序将Week类中的构造方法进行私有化处理,以后在类中准备了若干个实例化对象,之后若是要获取Week类的实例,只能使用MONDAY...SUNDAY7个对象,这样就有效的限制了对象的取值范围spa

以上使用的Week对象的指定范围,咱们发现是经过一个个常量对每一个对象进行了编号。也就是一个个对象就至关于用常量进行了标识,因此按照这个思路咱们也能够直接使用一个接口定义一组常量范围(这种方法我的使用较少)rest

package com.shxt.demo02;

public interface Week {
    //自动补全public static final
    int SUNDAY = 1;
    int MONDAY = 2;
    int TUESDAY = 3;
    int WEDNESDAY = 4;
    int THURSDAY = 5;
    int FRIDAY = 6;
    int SATURDAY = 7;
}
复制代码

可是经过接口的方式的枚举会存在问题,会存在结果操做不正确的问题code

package com.shxt.demo02;

public class WeekTest {
    public static void main(String[] args) {
        System.out.println(Week.SATURDAY+Week.FRIDAY);//星期的数据相加,没有该结果
    }
}
复制代码

使用咱们这种方式,用户想知道到底有多少星期可使用(假设你不知道),则实现的代码会比较复杂,还有就是牺牲也比较大,因此在JDK1.5以后就专门解决了相似的问题。对象

2.定义枚举类型

在JDK1.5以后,引入了一个新的关键字类型——enum,能够直接定义枚举类型,语法格式以下

public enum 枚举类型名称{
    枚举对象1,枚举对象2,枚举对象3,...,枚举对象N
}
复制代码

示例1:定义一个枚举类型

package com.shxt.demo03;
public enum Week {
    SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY;
}

复制代码

示例2:取出枚举内容

package com.shxt.demo03;

public class Test01 {
    public static void main(String[] args) {
        Week w = Week.MONDAY;//获得MONDAY
        System.out.println(w);
    }
}
/* 运行结果为:MONDAY */
复制代码

这个结果感受并无什么卵用,咱们须要一步步来,使用此方式好处能够避免以前使用接口方式的问题

package com.shxt.demo03;

public class Test02 {
    public static void main(String[] args) {
        System.out.println(Week.MONDAY+Week.FRIDAY);//错误
    }
}
复制代码

枚举类型的数据也可使用“枚举.values()”的形式,将所有的枚举类型变为对象数组的形式,以后直接使用foreach进行操做。

示例3:使用foreach输出枚举内容

package com.shxt.demo03;

public class Test03 {
    public static void main(String[] args) {
        Week[] weeks = Week.values();
        for (Week w : weeks){
            System.out.println(w);
        }
    }
}
复制代码

示例4:使用switch进行判断

如今的一切都是简单介绍,后面还有更加具体的介绍

package com.shxt.demo03;

public class Test04 {
    public static void main(String[] args) {
        Week[] weeks = Week.values();
        for (Week w : weeks){
            print(w);
        }
    }

    public static void print(Week week){
        switch (week){
            case SUNDAY:
                System.out.println("星期日");
                break;
            case MONDAY:
                System.out.println("星期一");
                break;
            case TUESDAY:
                System.out.println("星期二");
                break;
            case WEDNESDAY:
                System.out.println("星期三");
                break;
            case THURSDAY:
                System.out.println("星期四");
                break;
            case FRIDAY:
                System.out.println("星期五");
                break;
            case SATURDAY:
                System.out.println("星期六");
                break;
            default:
                System.out.println("什么鬼???");
                break;

        }
    }
}

复制代码

上述过程介绍的枚举的使用在实际开发中应用是很是少的,做为开发人员必需要进一步的深刻了解枚举类型

3.进一步深刻枚举类型

使用enum关键字能够定义一个枚举类型,实际上此关键字笔试的是java.lang.Enum类,使用enum声明的枚举类型就至关于定义一个类,而此类默认继承了java.lang.Enum类

public abstract class Enum<E extends Enum<E>> extends Object implements Comparable<E>, Serializable 复制代码
编号 方法名称 类型 描述
1 protected Enum(String name,int ordinal) 构造 接收枚举的名称和枚举常量建立枚举对象
2 protected final Object clone()
throws CloneNotSupportedException
普通 克隆枚举对象
3 public final int compareTo(E o) 普通 对象比较
4 public final boolean equals(Object other) 普通 比较两个枚举对象
5 public final int hashCode() 普通 返回枚举常量的哈希码
6 public final String name() 普通 返回此枚举的名称
7 public final int ordinal() 普通 返回枚举常量的序数
8 public static <T extends Enum> T
valueOf(Class enumType, String name)
普通 返回带指定名称的指定枚举类型的枚举常量

示例1:获取枚举的信息

package com.shxt.demo03;

public enum Week {
    SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY;
}
复制代码
package com.shxt.demo03;

public class Test05 {
    public static void main(String[] args) {
        for (Week w : Week.values()) {
            System.out.println(w.ordinal()+"->"+w.name());
        }
    }
}
/** 运行结果: 0->SUNDAY 1->MONDAY 2->TUESDAY 3->WEDNESDAY 4->THURSDAY 5->FRIDAY 6->SATURDAY */
复制代码

示例2:经过构造方法为属性赋值

每一个枚举类中都有其指定的若干个对象,固然,每一个枚举能够包含多个属性,必须在enum实例序列的最后添加一个分号,Java 要求必须先定义 enum 实例.

package com.shxt.demo04;

public enum Week {
    SUNDAY("星期日",7),MONDAY("星期一",1),TUESDAY("星期二",2),
    WEDNESDAY("星期三",3),THURSDAY("星期四",4),FRIDAY("星期五",5),SATURDAY("星期六",6);

    private String name;
    private int index;
    //构造方法
    private Week(String name,int index){
        this.name = name;
        this.index = index;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getIndex() {
        return index;
    }

    public void setIndex(int index) {
        this.index = index;
    }
}
复制代码

Week枚举类中增长了两个属性name和index,并经过私有构造方法设置name和index属性的内容,由于Week中已经明肯定义了两个参数的构造方法,因此枚举内容必需要调用该构造方法.

package com.shxt.demo04;

public class Test05 {
    public static void main(String[] args) {
        for (Week w : Week.values()) {
            System.out.println("序号:"+w.ordinal()+" 枚举名称:"+w.name()+" 属性name值:"+w.getName()+" 属性index值:"+w.getIndex());
        }
    }
}
/** 运行结果为: 序号:0 枚举名称:SUNDAY 属性name值:星期日 属性index值:7 序号:1 枚举名称:MONDAY 属性name值:星期一 属性index值:1 序号:2 枚举名称:TUESDAY 属性name值:星期二 属性index值:2 序号:3 枚举名称:WEDNESDAY 属性name值:星期三 属性index值:3 序号:4 枚举名称:THURSDAY 属性name值:星期四 属性index值:4 序号:5 枚举名称:FRIDAY 属性name值:星期五 属性index值:5 序号:6 枚举名称:SATURDAY 属性name值:星期六 属性index值:6 */
复制代码

示例3:覆盖枚举方法toString

package com.shxt.demo05;

public enum Week {
    SUNDAY("星期日",7),MONDAY("星期一",1),TUESDAY("星期二",2),
    WEDNESDAY("星期三",3),THURSDAY("星期四",4),FRIDAY("星期五",5),SATURDAY("星期六",6);

    private String name;
    private int index;
    //构造方法
    private Week(String name, int index){
        this.name = name;
        this.index = index;
    }

    @Override
    public String toString() {
        return "Week{" +
                "name='" + name + '\'' +
                ", index=" + index +
                '}';
    }
}

复制代码
package com.shxt.demo05;

public class Test05 {
    public static void main(String[] args) {
        for (Week w : Week.values()) {
            System.out.println(w);
        }
    }
}
/** 运行结果为: Week{name='星期日', index=7} Week{name='星期一', index=1} Week{name='星期二', index=2} Week{name='星期三', index=3} Week{name='星期四', index=4} Week{name='星期五', index=5} Week{name='星期六', index=6} */
复制代码

示例4:使用比较器

在Enum类中已经实现好了Comparable接口,因此枚举类的内容自己是能够进行排序的,只是测试一下结果,在类集的时候咱们介绍过TreeSet能够直接进行排序,排序规则是根据Comparable接口完成的

package com.shxt.demo06;

public enum Week {
    SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY;
}
复制代码
import java.util.TreeSet;

public class Test01 {
    public static void main(String[] args) {
        Set<Week> weekSet = new TreeSet<>();
        //乱存数据
        weekSet.add(Week.FRIDAY);
        weekSet.add(Week.MONDAY);
        weekSet.add(Week.THURSDAY);
        weekSet.add(Week.WEDNESDAY);
        weekSet.add(Week.TUESDAY);
        weekSet.add(Week.SATURDAY);
        weekSet.add(Week.SUNDAY);
        for (Week w:weekSet){
            System.out.println(w.ordinal()+"-->"+w.name());
        }
    }
}
复制代码

迭代出的数据顺序是根据ordinal属性进行排序的.

4.类集对枚举的支持

(1)EnumMap

EnumMap是Map接口中的子类,因此自己仍是以Map的形式进行操做,key=>value

package com.shxt.demo07;

public enum  Color {
    RED,YELLOW,BLUE;
}
复制代码
package com.shxt.demo07;

import java.util.EnumMap;
import java.util.Map;

public class EnumMapTest {
    public static void main(String[] args) {
        Map<Color,String> map = new EnumMap<Color, String>(Color.class);
        map.put(Color.RED,"红色");
        map.put(Color.YELLOW,"黄色");
        map.put(Color.BLUE,"蓝色");

        System.out.println("**********输出所有的枚举内容和其对应的值************");
        for(Color c : Color.values()){
            System.out.println(c.name()+" map中的value:"+map.get(c));
        }

        System.out.println("**********获取所有的键值***************************");
        for (Color c : map.keySet()){
            System.out.println("KEY="+c.name());
        }
        System.out.println("**********获取所有的内容***************************");
        for (String s : map.values()){
            System.out.println("Value="+s);
        }

    }
}

复制代码

上述的代码的应用场景我不太清楚,有清楚的请留言告知

(2)EnumSet

EnumSet是Set接口的子类,因此里面的内容是没法重复.使用EnumSet时不能直接使用关键字new为其进行实例化,而是使用本类提供的静态方法

序号 方法名称 类型 描述
1 public static <E extends Enum<E>>
EnumSet<E> allOf(Class<E> elementType)
普通 将枚举中的所有内容设置到EnumSet中
2 public static <E extends Enum<E>>
EnumSet<E> of(E first,E...rest)
普通 建立一个包含枚举指定内容的EnumSet对象
3 public static <E extends Enum<E>>
EnumSet<E> copyOf(Collection<E> c)
普通 建立一个从指定Collection中指定的EnumSet对象
4 public static <E extends Enum<E>>
EnumSet<E> complementOf(EnumSet<E> s)
普通 建立一个其元素类型与指定枚举 set 相同的枚举
set,最初包含指定 set 中所不 包含的此类型的全部元素。
5 public static <E extends Enum<E>>
EnumSet<E> noneOf(Class<E> e)
普通 建立一个能够接收指定类型的空集合

示例1:将所有的枚举设置到EnumSet集合中

package com.shxt.demo08;

import java.util.EnumSet;

enum  Color {
    RED,YELLOW,BLUE;
}

public class DenumSetDemo01 {

    public static void main(String[] args) {
        EnumSet<Color> set = EnumSet.allOf(Color.class);//将枚举的所有数据设置到EnumSet对象中

        for (Color c : set){
            System.out.println(c);
        }

    }

}
复制代码

示例2:设置一个枚举数据到EnumSet结合中

package com.shxt.demo08;

import java.util.EnumSet;

enum  Color {
    RED,YELLOW,BLUE;
}

public class DenumSetDemo02 {

    public static void main(String[] args) {
        EnumSet<Color> set = EnumSet.of(Color.YELLOW);//设置一个枚举内容

        for (Color c : set){
            System.out.println(c);
        }

    }

}

复制代码

示例3:只能放入指定的枚举类型的集合

package com.shxt.demo08;

import java.util.EnumSet;

enum  Color {
    RED,YELLOW,BLUE;
}

public class DenumSetDemo03 {

    public static void main(String[] args) {
        EnumSet<Color> set = EnumSet.noneOf(Color.class);//建立一个能够键入Color类型的对象
        set.add(Color.YELLOW);
        set.add(Color.BLUE);

        for (Color c : set){
            System.out.println(c);
        }

    }

}
复制代码

其余的方法就不作测试了,感受也没有什么实际的用处,这里就省略...见谅

5.让枚举实现一个接口

枚举类也能够实现一个接口,可是由于接口中存在的都是抽线方法,因此枚举类中的每一个对象必须分别实现接口中的抽象方法

package com.shxt.demo09;

interface Print{
    String getColor();
}

enum Color implements Print{
    RED{
        @Override
        public String getColor() {
            return "红色";
        }
    },YELLOW{
        @Override
        public String getColor() {
            return "黄色";
        }
    },BLUE{
        @Override
        public String getColor() {
            return "蓝色";
        }
    };
}

public class InterfaceEnumDemo01 {
    public static void main(String[] args) {
        for (Color c : Color.values()){
            System.out.println(c.getColor());
        }
    }
}

复制代码

或者这样写也是能够的

package com.shxt.demo10;

interface Print{
    String getColor();
}

enum Color implements Print {
   RED("红色"),YELLOW("黄色"),BLUE("蓝色");
   private String name;
   private Color(String name){
       this.name = name;
   }

    @Override
    public String getColor() {
        return this.name;
    }
}

public class InterfaceEnumDemo01 {
    public static void main(String[] args) {
        for (Color c : Color.values()){
            System.out.println(c.getColor());
        }
    }
}

复制代码

6.在枚举类中定义抽象方法

package com.shxt.demo11;


enum Color {
   RED("红色") {
       @Override
       public String getColor() {
           return "红红=>"+this.name;
       }
   },YELLOW("黄色") {
        @Override
        public String getColor() {
            return "黄黄=>"+this.name;
        }
    },BLUE("蓝色") {
        @Override
        public String getColor() {
            return "蓝蓝=>"+this.name;
        }
    };
   protected String name;
   private Color(String name){
       this.name = name;
   }


    public abstract String getColor() ;
}

public class AbstractEnumDemo01 {
    public static void main(String[] args) {
        for (Color c : Color.values()){
            System.out.println(c.getColor());
        }
    }
}

复制代码
相关文章
相关标签/搜索