一、简介
枚举是JDK1.5版本新增的特性(泛型、For-each等如今被广泛应用的特性也是由JDK1.5时所新增的),另外到了JDK1.6后switch语句支持枚举类型。
二、语法
public enum ColorEnum {
RED,BLUE,GREEN
}
之后便可以通过枚举类型名直接引用常量,如 ColorEnum.RED、ColorEnum.GREEN。
枚举类
Java 中的每一个枚举都继承自 java.lang.Enum 类。当定义一个枚举类型时,每一个枚举类型成员都可以看作是 Enum 类的实例,这些枚举成员默认都被 final、public, static 修饰,当使用枚举类型成员时,直接使用枚举名称调用成员即可。
所有枚举实例都可以调用 Enum 类的方法,常用方法如表 1 所示。
| 方法名称 | 描述 |
|---|---|
| values() | 以数组形式返回枚举类型的所有成员 |
| valueOf() | 将普通字符串转换为枚举实例 |
| compareTo() | 比较两个枚举成员在定义时的顺序 |
| ordinal() | 获取枚举成员的索引位置 |
例 2
通过调用枚举类型实例的 values() 方法可以将枚举的所有成员以数组形式返回,也可以通过该方法获取枚举类型的成员。
下面的示例创建一个包含 3 个成员的枚举类型 Signal,然后调用 values() 方法输出这些成员。
enum Signal{
// 定义一个枚举类型
GREEN, YELLOW, RED;
}
public static void main(String[] args)
{
for (int i = 0; i < Signal.values().length; i++)
{
System.out.println("枚举成员:" + Signal.values()[i]);
}
}
输出结果如下:
枚举成员:GREEN 枚举成员:YELLOW 枚举成员:RED
例 3
创建一个示例,调用valueOf() 方法获取枚举的一个成员,再调用 compareTo() 方法进行比较,并输出结果。具体实现代码如下:
public class TestEnum {
public enum Sex
{
//定义一个枚举
male, female;
}
public static void main(String[] args) {
compare(Sex.valueOf("male")); // 比较
}
public static void compare(Sex s) {
for (int i = 0; i < Sex.values().length; i++) {
System.out.println(s + "与" + Sex.values()[i] + "的比较结果是:" + s.compareTo(Sex.values()[i]));
}
}
}
上述代码中使用 Sex.valueOf("male") 取出枚举成员 male 对应的值,再将该值与其他枚举成员进行比较。最终输出结果如下:
male与male的比较结果是:0 male与female的比较结果是:-1
例 4
通过调用枚举类型实例的 ordinal() 方法可以获取一个成员在枚举中的索引位置。下面的示例创建一个包含 3 个成员的枚举类型 Signal,然后调用 ordinal() 方法输出成员及对应索引位置。
具体实现代码如下:
public class TestEnum1{
enum Signal{
//定义一个枚举类型
GREEN, YELLOW, RED;
}
public static void main(String[] args){
for (int i = 0; i < Signal.values().length; i++) {
System.out.println("索引" + Signal.values()[i].ordinal() + ",值:" + Signal.values()[i]);
}
}
}
输出结果如下:
索引0,值:GREEN 索引1,值:YELLOW 索引2,值:RED
DK1.6之前的switch语句只支持int,char,enum类型,使用枚举,能让我们的代码可读性更强。
enum Signal {
GREEN, YELLOW, RED
}
public class TrafficLight {
Signal color = Signal.RED;
public void change() {
switch (color) {
case RED:
color = Signal.GREEN;
break;
case YELLOW:
color = Signal.RED;
break;
case GREEN:
color = Signal.YELLOW;
break;
}
}
}
以上代码网上拷贝的,看完感觉没有啥意义,,,直接Signal.RED不就ok了么?下面switch没必要估计只是为了说明支持switch。
向枚举中添加新方法
如果打算自定义自己的方法,那么必须在enum实例序列的最后添加一个分号。而且 Java 要求必须先定义 enum 实例。
Java代码
public enum Color {
RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
// 成员变量
private String name;
private int index;
// 构造方法
private Color(String name, int index) {
this.name = name;
this.index = index;
}
// 普通方法
public static String getName(int index) {
for (Color c : Color.values()) {
if (c.getIndex() == index) {
return c.name;
}
}
return null;
}
// get set 方法
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;
}
}
覆盖枚举的方法
下面给出一个toString()方法覆盖的例子。
public enum Color {
RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
// 成员变量
private String name;
private int index;
// 构造方法
private Color(String name, int index) {
this.name = name;
this.index = index;
}
//覆盖方法
@Override
public String toString() {
return this.index+"_"+this.name;
}
}
实现接口
所有的枚举都继承自java.lang.Enum类。由于Java 不支持多继承,所以枚举对象不能再继承其他类。
public interface Behaviour {
void print();
String getInfo();
}
public enum Color implements Behaviour{
RED("红色", 1), GREEN("绿色", 2), BLANK("白色", 3), YELLO("黄色", 4);
// 成员变量
private String name;
private int index;
// 构造方法
private Color(String name, int index) {
this.name = name;
this.index = index;
}
//接口方法
@Override
public String getInfo() {
return this.name;
}
//接口方法
@Override
public void print() {
System.out.println(this.index+":"+this.name);
}
}
使用接口组织枚举
public interface Food {
enum Coffee implements Food{
BLACK_COFFEE,DECAF_COFFEE,LATTE,CAPPUCCINO
}
enum Dessert implements Food{
FRUIT, CAKE, GELATO
}
}
关于枚举集合的使用
EnumMap 与 EnumSet
为了更好地支持枚举类型,java.util 中添加了两个新类:EnumMap 和 EnumSet。使用它们可以更高效地操作枚举类型。
EnumMap 类
EnumMap 是专门为枚举类型量身定做的 Map 实现。虽然使用其他的 Map(如 HashMap)实现也能完成枚举类型实例到值的映射,但是使用 EnumMap 会更加高效。
HashMap 只能接收同一枚举类型的实例作为键值,并且由于枚举类型实例的数量相对固定并且有限,所以 EnumMap 使用数组来存放与枚举类型对应的值,使得 EnumMap 的效率非常高。
例 6
下面是使用 EnumMap 的一个代码示例。枚举类型 DataBaseType 里存放了现在支持的所有数据库类型。针对不同的数据库,一些数据库相关的方法需要返回不一样的值,例如示例中 getURL() 方法。
//定义数据库类型枚举
public enum DataBaseType{
MYSQUORACLE,DB2,SQLSERVER
}
//某类中定义的获取数据库URL的方法以及EnumMap的声明
private EnumMap<DataBaseType,String>urls=new EnumMap<DataBaseType,String>(DataBaseType.class);
public DataBaseInfo(){
urls.put(DataBaseType.DB2,"jdbc:db2://localhost:5000/sample");
urls.put(DataBaseType.MYSQL,"jdbc:mysql://localhost/mydb");
urls.put(DataBaseType.ORACLE,"jdbc:oracle:thin:@localhost:1521:sample");
urls.put(DataBaseType.SQLSERVER,"jdbc:microsoft:sqlserver://sql:1433;Database=mydb");
}
//根据不同的数据库类型,返回对应的URL
//@param type DataBaseType 枚举类新实例
//@return
public String getURL(DataBaseType type){
return this.urls.get(type);
}
在实际使用中,EnumMap 对象 urls 往往是由外部负责整个应用初始化的代码来填充的。这里为了演示方便,类自己做了内容填充。
从本例中可以看出,使用 EnumMap 可以很方便地为枚举类型在不同的环境中绑定到不同的值上。本例子中 getURL 绑定到 URL 上,在其他的代码中可能又被绑定到数据库驱动上去。
EnumSet 类
EnumSet 是枚举类型的高性能 Set 实现,它要求放入它的枚举常量必须属于同一枚举类型。EnumSet 提供了许多工厂方法以便于初始化,如表 2 所示。
| 方法名称 | 描述 |
|---|---|
| allOf(Class<E> element type) | 创建一个包含指定枚举类型中所有枚举成员的 EnumSet 对象 |
| complementOf(EnumSet<E> s) | 创建一个与指定 EnumSet 对象 s 相同的枚举类型 EnumSet 对象, 并包含所有 s 中未包含的枚举成员 |
| copyOf(EnumSet<E> s) | 创建一个与指定 EnumSet 对象 s 相同的枚举类型 EnumSet 对象, 并与 s 包含相同的枚举成员 |
| noneOf(<Class<E> elementType) | 创建指定枚举类型的空 EnumSet 对象 |
| of(E first,e...rest) | 创建包含指定枚举成员的 EnumSet 对象 |
| range(E from ,E to) | 创建一个 EnumSet 对象,该对象包含了 from 到 to 之间的所有枚 举成员 |
EnumSet 作为 Set 接口实现,它支持对包含的枚举常量的遍历。
纯文本复制
for(Operation op:EnumSet.range(Operation.PLUS,Operation.MULTIPLY)){
doSomeThing(op);
}
本文介绍了Java枚举类相关知识。枚举是JDK1.5新增特性,JDK1.6后switch语句支持枚举类型。详细讲解了枚举类语法,如向枚举中添加新方法、覆盖枚举方法、实现接口等,还介绍了使用接口组织枚举。此外,阐述了枚举集合EnumMap与EnumSet的使用,能更高效操作枚举类型。
221

被折叠的 条评论
为什么被折叠?



