网站首页 > 技术文章 正文
枚举是一个小功能,但是却带来了大方便。一个星期有七天,我们平时定义这七天为常量的时候,会这么写:
public final static String SUNDAY = "0"; public final static String MONDAY = "1"; public final static String TUESDAY = "2"; public final static String WEDNESDAY = "3"; public final static String THRUSDAY = "4"; public final static String FRIDAY = "5"; public final static String SATURDAY = "6";
有了枚举之后,就可以换一种写法了:
public enum EnumDay { SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THRUSDAY, FRIDAY, SATURDAY; }
这就定义了SUNDAY~SATURDAY的枚举了,使用枚举类型代替了常量,还提供了比常量更多的方法。枚举类型适用的数据有以下特点:
1、枚举值之间是有内在关联的,比如上面的,都是一个星期的七天
2、常量的值是随便的,比如SUNDAY必须是"12345",MONDAY必须是"23456"也可以用枚举,不过要麻烦些
上面的EnumDay其实隐含了所创建的类型都是java.lang.Enum类的子类,枚举类型符合通用模式Class Enum<E extends Enum<E>>,E表示的就是枚举类型的名称。枚举类型的每一个值都将映射到protected Enum<String name, int ordinal>构造函数中,在这里,每个值的名称都被转换为一个字符串,并且序数设置表示了此设置被创建的顺序。EnumDay实际调用了7此Enum:
new Enum<EnumDay>("SUNDAY", 0); new Enum<EnumDay>("MONDAY", 1); new Enum<EnumDay>("TUESDAY", 2); new Enum<EnumDay>("WEDNESDAY", 3); new Enum<EnumDay>("THRUSDAY", 4); new Enum<EnumDay>("FRIDAY", 5); new Enum<EnumDay>("SATURDAY", 6);
所以,只要记住每个枚举值都是一个泛型为EnumDay的Enum就可以了。
遍历枚举类型及枚举方法
既然知道了枚举类型里面的枚举值都是一个Enum<EnumDay>,那就好办了,可以查看JDK API来看下Enum里面有哪些方法并使用下,看一下例子:
public static void main(String[] args) throws Exception { EnumDay[] eds = EnumDay.values(); // 将EnumDay中的枚举值转换为EnumDay数组 int i = 0; for (EnumDay ed : eds) { System.out.println("EnumDay[" + i + "]:" + ed.toString()); // 返回枚举常量的名称 i++; } System.out.println(); System.out.println("Enum<EnumDay>.compareTo():" + eds[0].compareTo(eds[1])); // 比较此枚举与指定枚举的顺序,被比较对象小于、等于、大于比较对象时,分别返回负整数、0、正整数,只能和相同枚举类型相比较 System.out.println("Enum<EnumDay>.equals():" + eds[0].equals(eds[1])); // 比较指定两个枚举类型是否相同 System.out.println("Enum<EnumDay>.getDeclaringClass():" + eds[0].getDeclaringClass()); // 获取指定枚举值的枚举类型对应的Class对象 System.out.println("Enum<EnumDay>.hashCode():" + eds[0].hashCode()); // 获取指定枚举值对应的hashCode System.out.println("Enum<EnumDay>.name():" + eds[0].name()); // 获取指定枚举值的名称 System.out.println("Enum<EnumDay>.ordinal():" + eds[0].ordinal()); // 获取指定枚举值对应的序数 }
结果为:
EnumDay[0]:SUNDAY EnumDay[1]:MONDAY EnumDay[2]:TUESDAY EnumDay[3]:WEDNESDAY EnumDay[4]:THRUSDAY EnumDay[5]:FRIDAY EnumDay[6]:SATURDAY Enum<EnumDay>.compareTo():-1 Enum<EnumDay>.equals():false Enum<EnumDay>.getDeclaringClass():class com.xrq.test37.EnumDay Enum<EnumDay>.hashCode():1414159026 Enum<EnumDay>.name():SUNDAY Enum<EnumDay>.ordinal():0
看到toString()方法和name()方法的值是一样,可能有人会想,那要这两个方法干嘛?toString()方法这里因为没有重写,实际上这个方法被开发者重写之后,就打印出了开发者需要的内容了,没有重写toString()方法打印的就是name属性了,看一下Enum类的源代码就知道了。
为枚举类型中的枚举值定义数值----自定义属性和方法
不给枚举类型中的枚举值定义数值,那么数值是从0开始逐个加上去的,当然我们也可以给枚举类型中的枚举值自定义数值,这时就要在EnumDay里面自定义属性和方法了:
public enum EnumDay { SUNDAY(1234), MONDAY(2345), TUESDAY(3456), WEDNESDAY(4567), THRUSDAY(5678), FRIDAY(6789), SATURDAY(7890) { public String toString() { return super.toString(); } }; private int value; private EnumDay(int value) { this.value = value; } public int getValue() { return value; } }
main函数可以直接调用getValue()方法,因为每个枚举值都是一个EnumDay:
public static void main(String[] args) { EnumDay[] eds = EnumDay.values(); for (EnumDay ed : eds) { System.out.println(ed.name() + ":" + ed.getValue()); } }
运行结果为:
SUNDAY:1234 MONDAY:2345 TUESDAY:3456 WEDNESDAY:4567 THRUSDAY:5678 FRIDAY:6789 SATURDAY:7890
从例子中看到,可以为枚举类型自定义方法,也可以自定义属性,也可以重写父类中的方法(如果不自定义方法的话,只有toString()方法可以重写,因为只有它不是final的),枚举类型是Enum<E extends Enum<E>>,所以EnumDay也可以继承类,实现接口,定义更多的方法。
EnumSet、EnumMap
EnumSet和EnumMap是分别为枚举类型定制的Set和Map,看一下它们的用法:
public static void main(String[] args) { EnumSet<EnumDay> es = EnumSet.allOf(EnumDay.class); for (EnumDay ed : es) System.out.println(ed.name() + ":" + ed.ordinal()); System.out.println("\n-----EnumSet和EnumMap之间的分隔线-----\n"); EnumMap<EnumDay, String> em = new EnumMap<EnumDay, String>(EnumDay.class); em.put(EnumDay.SUNDAY, "星期天"); em.put(EnumDay.MONDAY, "星期一"); em.put(EnumDay.TUESDAY, "星期二"); em.put(EnumDay.WEDNESDAY, "星期三"); em.put(EnumDay.THRUSDAY, "星期四"); em.put(EnumDay.FRIDAY, "星期五"); em.put(EnumDay.SATURDAY, "星期六"); Iterator<Entry<EnumDay, String>> iterator = em.entrySet().iterator(); while (iterator.hasNext()) { Entry<EnumDay, String> entry = iterator.next(); System.out.println(entry.getKey().name() + ":" + entry.getValue()); } }
运行结果为:
SUNDAY:0 MONDAY:1 TUESDAY:2 WEDNESDAY:3 THRUSDAY:4 FRIDAY:5 SATURDAY:6 -----EnumSet和EnumMap之间的分隔线----- SUNDAY:星期天 MONDAY:星期一 TUESDAY:星期二 WEDNESDAY:星期三 THRUSDAY:星期四 FRIDAY:星期五 SATURDAY:星期六
注意一下EnumSet和EnumMap都是线程非安全的。
猜你喜欢
- 2024-10-27 从bitmap到布隆过滤器,再到高并发缓存设计策略
- 2024-10-27 强大 WebView2 + 不用写 JavaScript 的 htmx.js 「小轻快」开发桌面程序
- 2024-10-27 《JSP》第13节:JSP中的四大作用域介绍
- 2024-10-27 Java,FreeMarker,模板引擎,通过案例代码,学懂模板引擎
- 2024-10-27 面向对象的三大特性(c++面向对象的三大特性)
- 2024-10-27 教你分析9种 OOM 常见原因及解决方案
- 2024-10-27 可动态调节参数的线程池实现(动态调试工具有哪些)
- 2024-10-27 Java,基本类型和引用类型,强引用、软引用、弱引用、虚引用
- 2024-10-27 深入理解Java:类加载机制及反射(java常见类加载器)
- 2024-10-27 JVM系列-6.javap指令介绍(jvm调优)
- 02-21走进git时代, 你该怎么玩?_gits
- 02-21GitHub是什么?它可不仅仅是云中的Git版本控制器
- 02-21Git常用操作总结_git基本用法
- 02-21为什么互联网巨头使用Git而放弃SVN?(含核心命令与原理)
- 02-21Git 高级用法,喜欢就拿去用_git基本用法
- 02-21Git常用命令和Git团队使用规范指南
- 02-21总结几个常用的Git命令的使用方法
- 02-21Git工作原理和常用指令_git原理详解
- 最近发表
- 标签列表
-
- cmd/c (57)
- c++中::是什么意思 (57)
- sqlset (59)
- ps可以打开pdf格式吗 (58)
- phprequire_once (61)
- localstorage.removeitem (74)
- routermode (59)
- vector线程安全吗 (70)
- & (66)
- java (73)
- org.redisson (64)
- log.warn (60)
- cannotinstantiatethetype (62)
- js数组插入 (83)
- resttemplateokhttp (59)
- gormwherein (64)
- linux删除一个文件夹 (65)
- mac安装java (72)
- reader.onload (61)
- outofmemoryerror是什么意思 (64)
- flask文件上传 (63)
- eacces (67)
- 查看mysql是否启动 (70)
- java是值传递还是引用传递 (58)
- 无效的列索引 (74)