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. JS魔法堂:阻止元素被选中

    一.前言 在为IE5.5~9polyfill HTML5新特性placeholder时需要阻止元素被选中,因此在网上.书上查阅相关资料,记录在此以便日后查阅. 二.IE10+实现方式──CSS3 .u ...

  2. Event事件跨浏览器封装

    var Event = { //注册事件 addEvent: function(element,type,handler){ if(element.addEventListener){ //DOM2级 ...

  3. KMP - HDU 1711 Number Sequence

    Number Sequence Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  4. SQL compute by 的使用

    SQL compute by 的使用 摘自:http://www.cnblogs.com/Gavinzhao/archive/2010/07/12/1776107.html GROUP BY子句有个缺 ...

  5. 1 初识Orchard

    网上关于Orchard的介绍已经很多了,具体Orchard是干啥的我就不再啰嗦,这个系列的主要目的就是介绍学习和使用orchard的过程,和在此过程中碰到问题的解决方案.下面直接进入正题. 获取orc ...

  6. 运行QQ出现initialization failure 0x0000000c错误和浏览器上不了网

    出现QQ出现initialization failure 0x0000000c错误和浏览器上不了网的问题,原因是关机的时候没有正常关闭导致的. 解决方法: 1.我们在开始菜单栏中的附件中找到“命令提示 ...

  7. 用PHP实现Windows域验证

    系统集成中,可能会有这种需求 Windows 域验证本质上是LDAP验证 但在网上居然找不到详细的技术文档,可见不受待见之极.

  8. 通过代码的方式完成WCF服务的寄宿工作

    使用纯代码的方式进行服务寄宿 服务寄宿的目的是为了开启一个进程,为WCF服务提供一个运行的环境.通过为服务添加一个或者多个终结点,使之暴露给潜在的服务消费,服务消费者通过匹配的终结点对该服务进行调用, ...

  9. [PE结构分析] 5.IMAGE_OPTIONAL_HEADER

    结构体源代码如下: typedef struct _IMAGE_OPTIONAL_HEADER { // // Standard fields. // +18h WORD Magic; // 标志字, ...

  10. fibonacci数列的和取余(1)

    As we know , the Fibonacci numbers are defined as follows:  """" Given two numbe ...