用法一:常量

  在JDK1.5 之前,我们定义常量都是: public static fianl....。现在好了,有了枚举,可以把相关的常量分组到一个枚举类型里,而且枚举提供了比常量更多的方法。

public enum Color {
RED, GREEN, BLANK, YELLOW
}

用法二:switch

  JDK1.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;
}
}
}

用法三:向枚举中添加新方法

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

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
}
}

用法七:关于枚举集合的使用

如下内容有用到的代码:

public enum EnumTest01 {  

    UPDATE(1,"更新"),QUERY(2,"查询"),DELETE(3,"删除");
private Integer enumValue;
private String enumDesc; private EnumTest01(Integer enumValue, String enumDesc) {
this.enumValue = enumValue;
this.enumDesc = enumDesc;
} public int getEnumValue(){
return this.enumValue;
} public String getEnumDesc(){
return this.enumDesc;
}
}

EnumMap

  Map的实现类有很多种,EnumMap从名字我们可以看出这个Map是给枚举类用的。它的key为枚举元素,value自定义。在工作中我们也可以用其他的Map来实现我们关于枚举的需求,但是为什么要用这个EnumMap呢?因为它的性能高!为什么性能高?因为它的内部是用数组的数据结构来维护的!我们可以看一下它的源码实现:

put方法

public V put(K key, V value) {
typeCheck(key); int index = key.ordinal();
Object oldValue = vals[index];
vals[index] = maskNull(value);
if (oldValue == null)
size++;
return unmaskNull(oldValue);
}

  typeCheck是用来检查key的类型的,因为key只能为枚举元素。接下来的这一句int index = key.ordinal(); key.ordinal()这个就是我们上面说的枚举类型的序号,然后被当做数组的下标,放到vals这个数组里。那么get方法呢?

get方法

public V get(Object key) {
return (isValidKey(key) ?
unmaskNull(vals[((Enum<?>)key).ordinal()]) : null);
}

注意这一句话:vals[((Enum<?>)key).ordinal()]。这个不就是取得下标,根据下标获取数组中的值吗?!

remove方法

public V remove(Object key) {
if (!isValidKey(key))
return null;
int index = ((Enum<?>)key).ordinal();
Object oldValue = vals[index];
vals[index] = null;
if (oldValue != null)
size--;
return unmaskNull(oldValue);
}

remove方法的实现也是挺简单的,就是把相应下标的元素变为null,等着GC回收。

EnumSet

  EnumSet这是一个用来操作Enum的集合,是一个抽象类,它有两个继承类:JumboEnumSet和RegularEnumSet。在使用的时候,需要制定枚举类型。它的特点也是速度非常快,为什么速度很快呢?因为每次add的时候,每个枚举值只占一个长整型的一位。我们可以翻看源码来看看它的实现:

add方法

public boolean add(E e) {
typeCheck(e); long oldElements = elements;
elements |= (1L << ((Enum<?>)e).ordinal());
return elements != oldElements;
}

从中我们可以看出是先对一个长整型左移枚举类型的序列数,然后再和长整型 或 。

ps:其中值得我们引起注意的代码的实现是1L<<((Enum<?>)e).ordinal());这段代码,其实现了每个元素仅占一位的效果。

of方法

of方法有好几个重载的方法,它的作用是创建一个最初包含指定元素的枚举 Set。

EnumSet<EnumTest01> enumSets = EnumSet.of(EnumTest01.DELETE);

allOf

创建一个包含指定元素类型的所有元素的枚举 Set。

EnumSet<EnumTest01> enumSets = EnumSet.allOf(EnumTest01.class);

range方法

创建一个指定范围的Set。

EnumSet<EnumTest01> enumSets = EnumSet.range(EnumTest01.DELETE,EnumTest01.UPDATE);

noneOf方法

创建一个指定枚举类型的空set。

EnumSet<EnumTest01> enumSet = EnumSet.noneOf(EnumTest01.class);
enumSet.add(EnumTest01.DELETE);
enumSet.add(EnumTest01.UPDATE);
for (Iterator<EnumTest01> it = enumSet.iterator(); it.hasNext();) {
System.out.println(it.next().getEnumDesc());
}
for (EnumTest01 enumTest : enumSet) {
System.out.println(enumTest.getEnumDesc() + " ..... ");
}

copyOf方法

创建一个set的并copy所传入的集合中的枚举元素。

EnumSet<EnumTest01> enumSets = EnumSet.copyOf(enumSet);

回到目录|·(工)·)

K:java中枚举的常见用法的更多相关文章

  1. Java中枚举的常见用法

    在JDK1.5以后引入了一种新的类型,就是枚举(enum).enum是用来声明枚举类型数据,它可以像数组一样存储许多的元素,但是不同于数组的是,它除了数字不能存储以外, 其他类型的如字母.特殊符号.汉 ...

  2. JAVA中enum的常见用法

    JAVA中enum的常见用法包括:定义并添加方法.switch.遍历.EnumSet.EnumMap 1.定义enum并添加或覆盖方法 public Interface Behaviour{ void ...

  3. C++和Java中枚举enum的用法

    在C++和java中都有枚举enum这个关键字,但是它们之间又不太一样.对于C++来说,枚举是一系列命名了的整型常量,而且从枚举值转化为对应的整型值是在内部进行的.而对于Java来说,枚举更像一个类的 ...

  4. Java中枚举的写法和用法

            在公司代码中,用了一大堆的枚举,看得我好懵逼.下面开始看看枚举怎么写和怎么用. 一.枚举的写法         关于枚举的写法,网上好多这方面的知识.这里直接贴一个我自己写的枚举类的代 ...

  5. Guava中Predicate的常见用法

    Guava中Predicate的常见用法 1.  Predicate基本用法 guava提供了许多利用Functions和Predicates来操作Collections的工具,一般在 Iterabl ...

  6. Java中的Socket的用法

                                   Java中的Socket的用法 Java中的Socket分为普通的Socket和NioSocket. 普通Socket的用法 Java中的 ...

  7. Java中Date各种相关用法

    Java中Date各种相关用法(一) 1.计算某一月份的最大天数 Java代码 Calendar time=Calendar.getInstance(); time.clear(); time.set ...

  8. 巨人大哥谈Java中的Synchronized关键字用法

    巨人大哥谈Java中的Synchronized关键字用法 认识synchronized 对于写多线程程序的人来说,经常碰到的就是并发问题,对于容易出现并发问题的地方价格synchronized基本上就 ...

  9. Java中枚举的使用

    Java中枚举其实就是静态常量,今天发现枚举里面其实还能加方法,学习了下, 代码如下: package org.pine.test; import java.util.HashMap; import ...

随机推荐

  1. HDU4508--完全背包

    湫湫系列故事--减肥记I Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) Tot ...

  2. 深港澳大湾区第三次.NET技术交流会圆满成功

    2017年12月10日,一场以云.devops.微服务.容器是现在这个发展阶段的软件形态, 本次活动我们围绕这些话题介绍.NET生态下的发展本地社区活动,这次活动还得到如鹏网杨中科老师的大力支持开通网 ...

  3. Centos-6.5 + python3 + mysql5.6 环境搭建

    注意:Centos6.5 是刚装好的系统 yum install lrzsz  (ftp上传和下载) yum install -y gcc     yum install -y gcc gcc-c++ ...

  4. Chrome浏览器调试技巧

    本文主要讲解针对chrome浏览器的调试方案,对于其他浏览器其实大同小异. 先来入门一点的 DOM元素调试 看上图: 以上图表明的1,2,3,4,5标记说明: 1,为移动设备模拟器,chorme现在是 ...

  5. C#复习资料

    C#期末考试复习题 一.单项选择题(每小题2分,共20分) 1.在类作用域中能够通过直接使用该类的(   )成员名进行访问. A. 私有      B. 公用      C. 保护      D. 任 ...

  6. ArrayList与数组间的转换

    关键句:String[] array = (String[])list.toArray(new String[size]); public class Test { public static voi ...

  7. Android官方命令深入分析之AVD Manager

    作者:宋志辉 AVD Manager提供了一个图形用户接口,通过它你能够创建和管理AVDs. 你能够通过下面方式执行AVD Manager: Eclipse:选择 Window > Androi ...

  8. Java内存管理(一)

    好久没有写博客了,深感羞愧,今天聊一下Java的内存管理 简单介绍 Java相比传统语言(C,C++)的一个优势在于其能够自己主动管理内存.从而将开发人员管理内存任务剥离开来. 本文大体描写叙述了J2 ...

  9. linux系统编程:进程间通信-fifo

    进程间通信-fifo 进程间通信的还有一种方式是fifo. fifo是还有一种管道:有名管道.从名字能够看出.它也是队列. 使用fifo通信前,得先创建fifo $ mkfifo myfifo 随后仅 ...

  10. Configuring WS-Security UsernameToken and WS-SecureConversation (Symmetric Connection Creation)

    Context This procedure provides a detailed process of all necessary steps to secure Web Services wit ...