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年出版,到现在已经将 ...
随机推荐
- Http客户端识别的方法
Http用户识别的机制方法分为如下几种: 1).承载用户身份的HTTP首部 2).客户端IP地址跟踪,根据客户端IP地址进行识别 3).用户登录,用认证方式设别用户 4).使用胖URL,一种在UR ...
- [JS] JavaScript由浅入深(2) 进阶
本节,将围绕以下几点来讲. 知识点:多线程.作用域.闭包.this 先顶后看 1.多线程 在不支持H5的浏览器中.使用Concurrent.Thread.js. 在支持H5中,使用WebWork. 在 ...
- [Tool] PLSQL使用技巧
1.PL/SQL Developer保存自定义界面布局 Tools->Preferences->User Interface->Options->Autosave deskto ...
- Java读取Excel文件的几种方法
Java读取 Excel 文件的常用开源免费方法有以下几种: 1. JDBC-ODBC Excel Driver 2. jxl.jar 3. jcom.jar 4. poi.jar 简单介绍: 百度文 ...
- Dir /U /c 输出Unicode字符的特性
比如某个目录列表如下: D:\Spec\a.txtD:\Spec\Dir・C.txtD:\Spec\else.txtD:\Spec\קתקווה.dataD:\Spec\中・文.txt 直接dir / ...
- Hyperion Business Modeling for Microsoft Windows (32-bit)
介质包搜索 常见问题 说明 复查 许可证列表 以确定需要下载的产品程序包. 请选择产品程序包和平台,然后单击“查找”. 如果只有一项结果,则可以看到下载页.如果有多个结果,请选择一个,然后单 ...
- AEAI ESB V3.5.4开源发布,应用集成平台
AEAI ESB 应用集成平台为数通畅联的核心产品,本着分享传递的理念,数通畅联将ESB管理控制台项目开源,目的在于满足客户与伙伴的OEM需求,以及为广大IT爱好者的集成工具提供多一种选择,多一种便利 ...
- javaweb学习总结(三十二)——JDBC学习入门
一.JDBC相关概念介绍 1.1.数据库驱动 这里的驱动的概念和平时听到的那种驱动的概念是一样的,比如平时购买的声卡,网卡直接插到计算机上面是不能用的,必须要安装相应的驱动程序之后才能够使用声卡和网卡 ...
- 自定义动画方法animate
animate的使用方法:animate(params,speed,callback); 例子:animate({ right: "-=600px",height:"+= ...
- spring中的DisposableBean和InitializingBean,ApplicationContextAware的用法
在spring容器初始化bean和销毁bean的以前的操作有很多种, 目前我知道的有:在xml中定义的时候用init-method和destory-method,还有一种就是定义bean的时候实现Di ...