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

  1. Arrays are not compatible with generics, so it requires an unchecked cast and will not compile cleanly.
  2. Array does not know what its index represents, it has to be labeled to the output manually.
  3. 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.

  1. Clarity
  2. Safety
  3. 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的更多相关文章

  1. 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 ...

  2. 《Effective Java》读书笔记 - 6.枚举和注解

    Chapter 6 Enums and Annotations Item 30: Use enums instead of int constants Enum类型无非也是个普通的class,所以你可 ...

  3. Effective Java 目录

    <Effective Java>目录摘抄. 我知道这看起来很糟糕.当下,自己缺少实际操作,只能暂时摘抄下目录.随着,实践的增多,慢慢填充更多的示例. Chapter 2 Creating ...

  4. Effective Java 第三版——37. 使用EnumMap替代序数索引

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  5. Effective Java 第三版——33. 优先考虑类型安全的异构容器

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  6. Effective Java通俗理解(下)

    Effective Java通俗理解(上) 第31条:用实例域代替序数 枚举类型有一个ordinal方法,它范围该常量的序数从0开始,不建议使用这个方法,因为这不能很好地对枚举进行维护,正确应该是利用 ...

  7. 《Effective Java(中文第二版)》【PDF】下载

    <Effective Java(中文第二版)>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230382186 Java(中文第二版)& ...

  8. Effective Java 第三版——35. 使用实例属性替代序数

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  9. Effective Java 第三版——38. 使用接口模拟可扩展的枚举

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

随机推荐

  1. Http客户端识别的方法

      Http用户识别的机制方法分为如下几种: 1).承载用户身份的HTTP首部 2).客户端IP地址跟踪,根据客户端IP地址进行识别 3).用户登录,用认证方式设别用户 4).使用胖URL,一种在UR ...

  2. [JS] JavaScript由浅入深(2) 进阶

    本节,将围绕以下几点来讲. 知识点:多线程.作用域.闭包.this 先顶后看 1.多线程 在不支持H5的浏览器中.使用Concurrent.Thread.js. 在支持H5中,使用WebWork. 在 ...

  3. [Tool] PLSQL使用技巧

    1.PL/SQL Developer保存自定义界面布局 Tools->Preferences->User Interface->Options->Autosave deskto ...

  4. Java读取Excel文件的几种方法

    Java读取 Excel 文件的常用开源免费方法有以下几种: 1. JDBC-ODBC Excel Driver 2. jxl.jar 3. jcom.jar 4. poi.jar 简单介绍: 百度文 ...

  5. Dir /U /c 输出Unicode字符的特性

    比如某个目录列表如下: D:\Spec\a.txtD:\Spec\Dir・C.txtD:\Spec\else.txtD:\Spec\קתקווה.dataD:\Spec\中・文.txt 直接dir / ...

  6. Hyperion Business Modeling for Microsoft Windows (32-bit)

    介质包搜索 常见问题    说明   复查 许可证列表 以确定需要下载的产品程序包. 请选择产品程序包和平台,然后单击“查找”. 如果只有一项结果,则可以看到下载页.如果有多个结果,请选择一个,然后单 ...

  7. AEAI ESB V3.5.4开源发布,应用集成平台

    AEAI ESB 应用集成平台为数通畅联的核心产品,本着分享传递的理念,数通畅联将ESB管理控制台项目开源,目的在于满足客户与伙伴的OEM需求,以及为广大IT爱好者的集成工具提供多一种选择,多一种便利 ...

  8. javaweb学习总结(三十二)——JDBC学习入门

    一.JDBC相关概念介绍 1.1.数据库驱动 这里的驱动的概念和平时听到的那种驱动的概念是一样的,比如平时购买的声卡,网卡直接插到计算机上面是不能用的,必须要安装相应的驱动程序之后才能够使用声卡和网卡 ...

  9. 自定义动画方法animate

    animate的使用方法:animate(params,speed,callback); 例子:animate({ right: "-=600px",height:"+= ...

  10. spring中的DisposableBean和InitializingBean,ApplicationContextAware的用法

    在spring容器初始化bean和销毁bean的以前的操作有很多种, 目前我知道的有:在xml中定义的时候用init-method和destory-method,还有一种就是定义bean的时候实现Di ...