黑马程序员_java枚举的使用

1. 什么是枚举

所谓枚举是指将变量的值一一列举出来,变量的值只限于列举出来的值的范围内。比如星期,一年中的四季,颜色值等都可以使用枚举进行列举出来。

2. 枚举类的前世今生

在jdk5以前的,要使用枚举那是不可能的,因为那个时候还没有呢,从5之后就有了枚举。其实一个枚举中的实例对象都是被static final 修饰的,因此我们可以使用普通的类进行模拟。

// 使用普通类来模拟一个枚举类(类用来描述星期)

// 不带抽象方法

public class WeekDay {

// 禁止创建对象

private WeekDay(){

}

public final static WeekDay MON = new WeekDay();

public final static WeekDay TUE = new WeekDay();

public final static WeekDay WED = new WeekDay();

public final static WeekDay THU = new WeekDay();

public final static WeekDay FRI = new WeekDay();

public final static WeekDay SAT = new WeekDay();

public final static WeekDay SUN = new WeekDay();

public WeekDay nextDay(){

if(this==MON)

return TUE;

else if(this==TUE)

return WED;

else if(this==WED)

return THU;

else if(this==THU)

return FRI;

else if(this==FRI)

return SAT;

else

return SUN;

}

public WeekDay aboveDay(){

if(this==MON)

return SUN;

else if(this==TUE)

return MON;

else if(this==WED)

return TUE;

else if(this==THU)

return WED;

else if(this==FRI)

return THU;

else

return SAT;

}

// Sunday(星期天)、Monday(星期一)、Tuesday(星期二)

// Wednesday(星期三)、Thursday(星期四)、Friday(星期五)、Saturday(星期六)。

public String toString(){

if(this == MON)

return "Monday";

else if(this == TUE)

return "Tuesday";

else if(this == WED)

return "Wednesday";

else if(this == THU)

return "Thursday";

else if(this == FRI)

return "Friday";

else if(this == SAT)

return "Saturday";

else

return "Sunday";

}

// 返回该星期在数字中的索引

public int ordinal() {

if(this == MON)

return 0;

else if(this == TUE)

return 1;

else if(this == WED)

return 2;

else if(this == THU)

return 3;

else if(this == FRI)

return 4;

else if(this == SAT)

return 5;

else

return 6;

}

}

// 使用普通类来模拟一个枚举类(类用来描述星期)

// 带抽象方法和构造函数的

public abstract class WeekDay1 {

// 模拟枚举中的成员实例

public final static WeekDay1 MON = new WeekDay1(1){

@Override

public WeekDay1 nextDay() {

return TUE;

}

@Override

public WeekDay1 aboveDay() {

return SUN;

}};

public final static WeekDay1 TUE = new WeekDay1(2){

@Override

public WeekDay1 nextDay() {

return WED;

}

@Override

public WeekDay1 aboveDay() {

return TUE;

}};

public final static WeekDay1 WED = new WeekDay1(3){

@Override

public WeekDay1 nextDay() {

return THU;

}

@Override

public WeekDay1 aboveDay() {

return TUE;

}

};

public final static WeekDay1 THU = new WeekDay1(4){

@Override

public WeekDay1 nextDay() {

return FRI;

}

@Override

public WeekDay1 aboveDay() {

return WED;

}

};

public final static WeekDay1 FRI = new WeekDay1(5){

@Override

public WeekDay1 nextDay() {

return SAT;

}

@Override

public WeekDay1 aboveDay() {

return THU;

}

};

public final static WeekDay1 SAT = new WeekDay1(6){

@Override

public WeekDay1 nextDay() {

return SUN;

}

@Override

public WeekDay1 aboveDay() {

return FRI;

}

};

public final static WeekDay1 SUN = new WeekDay1(0){

@Override

public WeekDay1 nextDay() {

return null;

}

@Override

public WeekDay1 aboveDay() {

return null;

}

};

private int index;

private WeekDay1(){};           // 默认构造器

private WeekDay1(int index){    // 自定义构造器

this.index = index;

}

public abstract WeekDay1 nextDay();

public abstract WeekDay1 aboveDay();

// Sunday(星期天)、Monday(星期一)、Tuesday(星期二)

// Wednesday(星期三)、Thursday(星期四)、Friday(星期五)、Saturday(星期六)

public String toString(){

if(this == MON)

return "Monday";

else if(this == TUE)

return "Tuesday";

else if(this == WED)

return "Wednesday";

else if(this == THU)

return "Thursday";

else if(this == FRI)

return "Friday";

else if(this == SAT)

return "Saturday";

else

return "Sunday";

}

public int ordinal(){

return this.index;

}

}

自从有了枚举之后,我们就可以这样来定义一个枚举了,给我们的开发带来了诸多的方便。枚举类中的多种常用的方法我们都可以使用了,相当的方便。

public enum WeekDay{

MON, TUE, WED, THU, FRI, SAT, SUN;

}

3. 枚举的特点

1) 用enum定义的枚举默认继承了java.lang.Enum类而不是继承了Object类。其中java.lang.Enum类实现了java.lang.Serializable和java.lang.Comparable两个接口。

2) 枚举类的构造方法只能使用private作为访问修饰符,如果省略了构造方法的访问修饰符,那么他会默认使用private作为访问修饰符。

3) 枚举类的所有实例成员都会显示的列出,系统会自动添加public static final进行修饰。无需我们手动进行添加。

4. 枚举的遍历

枚举的遍历我们使用增强for循环进行遍历,如下代码显示:

// 不带构造方法和带构造方法枚举

public enum WeekDay{

MON, TUE, WED, THU, FRI, SAT, SUN;

}

因为WeekDay.values()返回的是一个WeekDay类型的数组。

for(WeekDay w : WeekDay.values()){

System.out.println(w);

}

5. 枚举的常用方法

int compareTo方法,将两个枚举实例进行比较

String name() 返回枚举实例的名称

int ordinal() 返回枚举值在枚举中的索引

String toString() 返回枚举的实例名称 比name更常用

public static valueOf(String name)  根据字符串形式的枚举值得到一个枚举实例

public class EnumTest2 {

public static void main(String[] args) {

WeekDay week = WeekDay.MON;

System.out.println(week.toString());

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

System.out.println(week.ordinal());

// 使用一个字符串返回一个枚举实例

WeekDay week2 = WeekDay.valueOf("TUE");

System.out.println(week2.toString());

WeekDay week3 = WeekDay.valueOf(WeekDay.class, "FRI");

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

}

//  不带构造方法和带构造方法枚举

public enum WeekDay{

MON, TUE, WED, THU, FRI, SAT, SUN;

}

}

6. 枚举的高级用法

在一个枚举类中我们可以自定义构造方法,还可以定义抽象的方法和非抽象的方法。枚举实例要放置在最前边,枚举类中的成员变量和方法都放在后边

// 不带构造方法和带构造方法枚举

public enum WeekDay{

MON(1), TUE(), WED, THU, FRI, SAT, SUN;

WeekDay(){

System.out.println("first");

}

WeekDay(int index){

System.out.println("second"+index);

}

}

要是枚举类中有抽象方法,那么枚举实例在开始就要对其复写。

public class Test {

public static void main(String[] args) {

WeekDay week = WeekDay.MON;

System.out.println(week.toString());

System.out.println(week.ordinal());

week.getWeekday();

}

// 带构造方法和抽象方法以及非抽象方法的枚举

public enum WeekDay{

MON(1){

@Override

public WeekDay nextDay() {

return TUE;

}},

TUE(){

@Override

public WeekDay nextDay() {

return WED;

}},

WED{

@Override

public WeekDay nextDay() {

return THU;

}},

THU{

@Override

public WeekDay nextDay() {

return FRI;

}},

FRI{

@Override

public WeekDay nextDay() {

return SAT;

}},

SAT{

@Override

public WeekDay nextDay() {

return SUN;

}},

SUN{

@Override

public WeekDay nextDay() {

return MON;

}};

WeekDay(){

System.out.println("first");

}

WeekDay(int index){

System.out.println("second"+index);

}

public abstract WeekDay nextDay();

public void getWeekday(){

System.out.println("The weekday is "+SAT.toString()+" and "+SUN.toString());

}

}

}

7. 枚举应用的实例,交通灯系统

public enum Lamp {

// 每个枚举元素各表示一个方向的控制灯

S2N("N2S","S2W",false),S2W("N2E","E2W",false),

E2W("W2E","E2S",false),E2S("W2N","S2N",false),

// 下面元素表示与上面的元素的相反方向的灯,它们的“相反方向灯”和“下一个灯”应忽略不计!

N2S(null,null,false),N2E(null,null,false),

W2E(null,null,false),W2N(null,null,false),

// 由南向东和由西向北等右拐弯的灯不受红绿灯的控制,所以,可以假想它们总是绿灯

S2E(null,null,true),E2N(null,null,true),

N2W(null,null,true),W2S(null,null,true);

private Lamp(String opposite,String next,boolean lighted){

this.opposite = opposite;

this.next = next;

this.lighted = lighted;

}

// 当前灯是否为绿

private boolean lighted;

// 与当前灯同时为绿的对应方向

private String opposite;

// 当前灯变红时下一个变绿的灯

private String next;

public boolean isLighted(){

return lighted;

}

// 某个灯变绿时,它对应方向的灯也要变绿

public void light(){

this.lighted = true;

if(opposite != null){

Lamp.valueOf(opposite).light();

}

System.out.println(name() + " lamp is green,下面总共应该有6个方向能看到汽车穿过!");

}

//  某个灯变红时,对应方向的灯也要变红,并且下一个方向的灯要变绿

// @return 下一个要变绿的灯

public Lamp blackOut(){

this.lighted = false;

if(opposite != null){

Lamp.valueOf(opposite).blackOut();

}

Lamp nextLamp= null;

if(next != null){

nextLamp = Lamp.valueOf(next);

System.out.println("绿灯从" + name() + "-------->切换为" + next);

nextLamp.light();

}

return nextLamp;

}

}

8. 总结

枚举这种全新的类型的出现很方便,这种类型像是对象也像数组。其实枚举成员也是一个实例,对于一个变量有限的值进行描述的时候,我们提倡使用枚举。枚举中封装的方法都很好用,可以提高效率,对每个值都能进行详细的描述。当这个枚举中有一个枚举值的时候我们可以当做单例设计模式来使用。枚举的出现,简化了开发,但是枚举的高级用法也是相当复杂,要是使用不当会降低代码的可读性。

时间: 2024-08-11 09:47:56

黑马程序员_java枚举的使用的相关文章

黑马程序员_JAVA 基础加强学习笔记

一.面向对象 (一)继承  1.继承的好处: (1) 提高了代码的复用性. (2) 让类与类之间产生了关系,提供了另一个特征多态的前提. 注意: 子类中所有的构造函数都会默认访问父类中的空参数的构造函数,因为每一个子类构造内第一行都有默认的语句super();  如果父类中没有空参数的构造函数,那么子类的构造函数内,必须通过super语句指定要访问的父类中的构造函数. 如果子类构造函数中用this来指定调用子类自己的构造函数,那么被调用的构造函数也一样会访问父类中的构造函数. 2.final特点

黑马程序员_Java基础加强(下)

8.注解类 注解相当于一种标记,加了注解就等于打上了某种标记,没加就等于没打特殊标记,开发工具和其他程序可以用反射来了解你的类及各种元素上有无何种标记,看你有什么标记就去干什么事,标记可以加在包.类.字段.方法,方法的参数以及局部变量上. 注解的应用结构图: 为注解增加属性 定义基本类型的属性和应用属性 在注解类中增加String color(); @MyAnnotation(color = "red") 用反射方式获得注解对应的实例对象后,再通过该对象调用属性对应的方法 MyAnno

黑马程序员_Java基础加强(上)

1.静态导入 静态导入是jdk1.5版本以后出现的新特性,一般是指导入静态方法,如:import static java.lang.System.out 是指导入系统输出的静态方法. 例: import static java.lang.System.out //导入java.lang包下的System类的静态方法out public class StaticImport { public static void main(String[] args) { int x=1; x++; out.p

黑马程序员_Java IO(下)

1,字符编码 在Java程序的开发中最常见的是ISO8859-1,GBK/GBK2312,unicode,UTF编码. ISO8859-1:属于单字节编码,最多只能表示0-255的字符范围,主要在英文上应用. GBK/GB2312:中文的国际编码,专门用来表示汉字,是双字节编码,如果在此编码中出现中文,则使用ISO8859-1编码,GBK可以表示简体中文和繁体中文,而GB2312只能表示简体中文,GBK兼容GB2312 unicode:Java中使用此编码方式,是最标准的一种编码,使用十六进制进

黑马程序员_Java高新技术

1  JDK5的新特性 1.1 静态导入       在API中那些不需要new对象的类,可以在类文件的开头,import static java.lang.Math.*;这里把Math中的所有的静态方法都导入了,在类中不需要调用Math类就能直接用Math的方法了 package cn.wjd.staticimport; import static java.lang.Math.*; public class StaticImport { public static void main(Str

黑马程序员_Java基础_接口

------- android培训.java培训.期待与您交流! ---------- 0.接口知识体系 Java接口的知识体系如下图所示,掌握下图中的所有知识就可精通接口. 1.接口概论 1)接口概念 接口是从多个相似类中抽象出来的规范,接口中不包含普通方法,所有方法都是抽象方法,接口不提供实现.接口体现的是规范和实现分离的哲学.规范和实现分离正是接口的好处,让软件系统的各个组件之间面向接口耦合,是一种松耦合的设计.接口定义的是多个类共同的公共行为规范,定义的是一组公用方法. 2)接口与抽象类

黑马程序员_Java反射机制

一切的操作都将使用Object完成,类,数组的引用都可以使用Object来接收 1,认识Class类 以前要是想知道一个类中的属性,成员变量,方法等等的信息的话,需要通过new这个类的对象才能得到这些信息,但是在Java中,也允许一个实例化对象找到一个类的完整的信息,这个类就是Class类,Class类是继承Object类的. 正常方式:  引入需要的"包.类"名称 >取得实例化对象 反射方式:  实例化对象>得到完整的"包.类"名称 getClass(

黑马程序员_Java多线程

- - - - - android培训.java培训.期待与您交流! - - - - - - 进程:正在进行中的程序.其实进程就是一个应用程序运行时的内存分配空间.进程负责的是应用程序的空间的标示. 线程:其实就是进程中一个程序执行控制单元,一条执行路径.线程负责的是应用程序的执行顺序. 一个进程至少有一个线程在运行,当一个进程中出现多个线程时,就称这个应用程序是多线程应用程序. 每个线程在栈区中都有自己的执行空间,自己的方法区.自己的变量. jvm在启动的时,首先有一个主线程,负责程序的执行,

黑马程序员_Java集合框架

- - - - - android培训.java培训.期待与您交流! - - - - - - 集合框架:用于存储数据的容器. 特点: 对象封装数据,对象多了也需要存储.集合用于存储对象. 对象的个数确定可以使用数组.如果不确定可以用集合.因为集合是可变长度的. 集合和数组的区别: 数组是固定长度的:集合可变长度的. 数组可以存储基本数据类型,也可以存储引用数据类型:集合只能存储引用数据类型. 数组存储的元素必须是同一个数据类型:集合存储的对象可以是不同数据类型. 数据结构:就是容器中存储数据的方