Effective Java 33 Use EnumMap instead of ordinal indexing
Wrong practice: Putting sets into an array indexed by the type's ordinal
/**
* Added demo for the "Use EnumMap instead of ordinal indexing".
*/
package com.effectivejava.EnumAnnotations;
/**
* @author Kaibo
*
*/
public class Herb {
public enum Type {
ANNUAL, PERENNIAL, BIENNIAL
}
private final String name;
public final Type type;
public Herb(String name, Type type) {
this.name = name;
this.type = type;
}
@Override
public String toString() {
return name;
}
}
// Using ordinal() to index an array - DON'T DO THIS!
Herb[] garden = ... ;
Set<Herb>[] herbsByType = // Indexed by Herb.Type.ordinal()
(Set<Herb>[])new Set[Herb.Type.values().length];
for (int i = 0; i < herbsByType.length; i++)
herbsByType[i] = new HashSet<Herb>();
for (Herb h : garden)
herbsByType[h.type.ordinal()].add(h);
// Print the results
for (int i = 0; i < herbsByType.length; i++) {
System.out.printf("%s: %s%n", Herb.Type.values()[i], herbsByType[i]);
}
Disadvantage of above case
- Arrays are not compatible with generics, so it requires an unchecked cast and will not compile cleanly.
- Array does not know what its index represents, it has to be labeled to the output manually.
- You have to be responsible to use the correct int value of an array; ints do not provide the type safety of enums.
Advantages of using EnumMap for multidimensional sets.
- Clarity
- Safety
- Ease of maintenance.
/**
* Added demo for the "Use EnumMap instead of ordinal indexing".
*/
package com.effectivejava.EnumAnnotations.unittest;
import java.util.EnumMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.junit.Test;
import com.effectivejava.EnumAnnotations.Herb;
/**
* @author Kaibo
*
*/
public class HerbTest {
@Test
public void test() {
// Using ordinal() to index an array - DON'T DO THIS!
Herb[] garden = {new Herb("Flower1",Herb.Type.ANNUAL),
new Herb("Flower2",Herb.Type.BIENNIAL),
new Herb("Flower3",Herb.Type.BIENNIAL)} ;
// Using an EnumMap to associate data with an enum
Map<Herb.Type, Set<Herb>> herbsByType = new EnumMap<Herb.Type, Set<Herb>>(
Herb.Type.class);
for (Herb.Type t : Herb.Type.values())
herbsByType.put(t, new HashSet<Herb>());
for (Herb h : garden)
herbsByType.get(h.type).add(h);
System.out.println(herbsByType);
}
}
Summary
It is rarely appropriate to use ordinals to index arrays: use EnumMap instead. If the relationship that you are representing is multidimensional, use EnumMap<..., EnumMap<...>>.
/**
* Added multidimensional Enum types demo for the "Use EnumMap instead of ordinal indexing".
*/
package com.effectivejava.EnumAnnotations;
import java.util.EnumMap;
import java.util.Map;
/**
* @author Kaibo
*
*/
public enum Phase {
SOLID, LIQUID, GAS;
public enum Transition {
MELT(SOLID, LIQUID), FREEZE(LIQUID, SOLID), BOIL(LIQUID, GAS), CONDENSE(
GAS, LIQUID), SUBLIME(SOLID, GAS), DEPOSIT(GAS, SOLID);
final Phase src;
final Phase dst;
Transition(Phase src, Phase dst) {
this.src = src;
this.dst = dst;
}
// Initialize the phase transition map
private static final Map<Phase, Map<Phase, Transition>> m = new EnumMap<Phase, Map<Phase, Transition>>(
Phase.class);
static {
for (Phase p : Phase.values())
m.put(p, new EnumMap<Phase, Transition>(Phase.class));
for (Transition trans : Transition.values())
m.get(trans.src).put(trans.dst, trans);
}
public static Transition from(Phase src, Phase dst) {
return m.get(src).get(dst);
}
}
}
Effective Java 33 Use EnumMap instead of ordinal indexing的更多相关文章
- Effective Java Index
Hi guys, I am happy to tell you that I am moving to the open source world. And Java is the 1st langu ...
- 《Effective Java》读书笔记 - 6.枚举和注解
Chapter 6 Enums and Annotations Item 30: Use enums instead of int constants Enum类型无非也是个普通的class,所以你可 ...
- Effective Java 目录
<Effective Java>目录摘抄. 我知道这看起来很糟糕.当下,自己缺少实际操作,只能暂时摘抄下目录.随着,实践的增多,慢慢填充更多的示例. Chapter 2 Creating ...
- Effective Java 第三版——37. 使用EnumMap替代序数索引
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- Effective Java 第三版——33. 优先考虑类型安全的异构容器
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- Effective Java通俗理解(下)
Effective Java通俗理解(上) 第31条:用实例域代替序数 枚举类型有一个ordinal方法,它范围该常量的序数从0开始,不建议使用这个方法,因为这不能很好地对枚举进行维护,正确应该是利用 ...
- 《Effective Java(中文第二版)》【PDF】下载
<Effective Java(中文第二版)>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230382186 Java(中文第二版)& ...
- Effective Java 第三版——35. 使用实例属性替代序数
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
- Effective Java 第三版——38. 使用接口模拟可扩展的枚举
Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...
随机推荐
- Python 的字符串格式化和颜色控制
(部分内容源自武神博客和网络收集.) Python的字符串格式化有两种方式: 百分号方式.format方式 百分号的方式相对来说比较老,而format方式则是比较先进的方式,企图替换古老的方式,目前两 ...
- python编码声明的位置很重要
python在3.x版本之前,编码一直是一个很头痛的问题.在代码中如果要使用中文,通常都要在文件的头部注明# -*- coding:utf-8 -*- 这样IDE或者解释器才会智能的转换编码. 这其中 ...
- SQL Server添加MDW性能监控报表
10.2 Data Collector与MDW Data Collection功能是SQL SERVER 2005版本提供的数据库监控报表的功能,通过定时地对数据库的语句运行情况,服务器各种资源的监控 ...
- [爬虫学习笔记]Url过滤模块UrlFilter
Url Filter则是对提取出来的URL再进行一次筛选.不同的应用筛选的标准是不一样的,比如对于baidu/google的搜索,一般不进行筛选,但是对于垂直搜索或者定向抓取的应用,那 ...
- jquery实现表格内容筛选
对于表格来说,当数据比较多的时候,我们无法一页一页的查找,这时可以通过一个搜索框来实现搜索. 对于这个搜素框,我们为了更好的体验可以利用keyup事件实现在用户输入的时候就开始筛选,而不是填完以后点击 ...
- 记录一款不错的插件fullpage.js
下载链接包括一些实例: http://www.dowebok.com/demo/2014/77/ 当然也可以从Github 上下载: https://github.com/alvarotrigo/fu ...
- 合并多个dll为一个dll
有时候自己写个小工具或者其它啥的物件,引用了好多第三方控件,如log4net,aspnetpager啥的,发布出去让别人看到自己竟然用了这么多的第三方DLL, 会对自己的能力产生怀疑,那有什么办法可以 ...
- vs2012中编译时出现程序集所使用的版本高于所引用的版本
我在运行别人的项目时出现版本不兼容的问题:
- eclipse优化与标准化记录
1.文件使用UTF-8格式: 2.取消js验证: 3.设置java文件模板
- mysql ALL_O_DIRECT引发的unaligned AIO/DIO导致hang
公司内部有一套mysql环境,使用的是percona server分支(和其他几十套环境的版本.参数完全相同),就这套环境每隔两三天就会hang一次,关键hang的时候服务器cpu也就是百分之三四十, ...