Java中EnumMap代替序数索引代码详解

 更新时间:2018年02月01日 10:00:28   作者:司马懿字仲达  
这篇文章主要介绍了Java中EnumMap代替序数索引代码详解,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下

本文研究的主要是Java中EnumMap代替序数索引的相关内容,具体介绍如下。

学习笔记《Effective Java 中文版 第2版》

经常会碰到使用Enum的ordinal方法来索引枚举类型。

public class Herb {
  public enum Type { ANNUAL, PERENNIAL, BIENNIAL };
  private final String name;
  private final Type type;

  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 = ... ;

//Indexed by Herb.Type.ordinal()
Set<Herb>[] herbsByType = (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]);
}

这种方法的确可行,但是隐藏着许多问题。因为数组不能与泛型兼容。程序需要进行未受检的转换,并且不能正确无误地进行编译。因为数组不知道它的索引代表着什么,你必须手工标注这些索引的输出。但是这种方法最严重的问题在于,当你访问一个按照枚举的序数进行索引的数组时,使用正确的int值就是你的职责了;int不能提供枚举的类型安全。你如果使用了错误的值,程序就会悄然地完成错误的工作,或者幸运的话就会抛出ArrayIndexOutOfBoundException异常。

java.util.EnumMap是一种非常快速的Map实现专门用于枚举的键。

//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);

这段程序更简短,更清楚,也更安全,运行速度方面可以与使用序数的程序相媲美。它没有不安全的转换;不必手工标注出这些索引的输出,因为映射键知道如何将自身翻译成可打印的字符串的枚举;计算数组索引时也不可能出错。EnumMap在运行速度方面之所以能与通过序数索引的数组相媲美,是因为EnumMap在内部使用了这种数组。但是它对程序员隐藏了这种思想细节,集Map的丰富功能和类型安全与数组的快速于一身。注意EnumMap构造器采用键类型的Class对象:这是一个有限制的类型令牌(bounded type token),它提供了运行时的泛型信息。

总结

以上就是本文关于Java中EnumMap代替序数索引代码详解的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站其他相关专题,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!

相关文章

  • java Hibernate 一对多自身关联问题

    java Hibernate 一对多自身关联问题

    formBean在提交表单的时候,域中数据库在下一次中仍然保留引起的,struts formBean 默认的scope为session,手动设置为request,就好了
    2008-07-07
  • 简单了解springboot加载配置文件顺序

    简单了解springboot加载配置文件顺序

    这篇文章主要介绍了简单了解springboot加载配置文件顺序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • 一文了解为什么Java中只有值传递

    一文了解为什么Java中只有值传递

    Java 传参是值传递还是引用传递?这个问题很基础,但是许多人都有点懵。本文就来通过一些示例带大家详细了解一下,需要的可以参考一下
    2022-07-07
  • Spring boot 集成Dubbox的方法示例

    Spring boot 集成Dubbox的方法示例

    本篇文章主要介绍了Spring boot 集成Dubbox的方法示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • Java调用外接设备详解(制卡机)

    Java调用外接设备详解(制卡机)

    这篇文章主要为大家详细介绍了Java调用外接设备的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-07-07
  • MybatisPlus:使用SQL保留字(关键字)的操作

    MybatisPlus:使用SQL保留字(关键字)的操作

    这篇文章主要介绍了MybatisPlus:使用SQL保留字(关键字)的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • java实现希尔排序算法

    java实现希尔排序算法

    希尔排序(Shell Sort)是插入排序的一种,是针对直接插入排序算法的改进,是将整个无序列分割成若干小的子序列分别进行插入排序,希尔排序并不稳定。该方法又称缩小增量排序,因DL.Shell于1959年提出而得名。
    2015-04-04
  • 基于springboot集成hbase过程解析

    基于springboot集成hbase过程解析

    这篇文章主要介绍了基于springboot集成hbase过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • Mybatisplus创建Spring Boot工程打包错误的解决方式

    Mybatisplus创建Spring Boot工程打包错误的解决方式

    最近在实战springboot遇到了一些坑,记录一下,下面这篇文章主要给大家介绍了关于Mybatisplus创建Spring Boot工程打包错误的解决方式,文中通过图文介绍的介绍的非常详细,需要的朋友可以参考下
    2023-03-03
  • Spring Security实现自定义访问策略

    Spring Security实现自定义访问策略

    本文介绍Spring Security实现自定义访问策略,当根据谁访问哪个域对象做出安全决策时,您可能需要一个自定义的访问决策投票者,幸运的是,Spring Security有很多这样的选项来实现访问控制列表(ACL)约束,下面就来学习Spring Security自定义访问策略,需要的朋友可以参考下
    2022-02-02

最新评论