容器--EnumMap
一、概述
EnumMap是一类特殊的Map, 其特殊之处在于KEY需要是枚举类型,由于枚举类型的特点是值的个数是固定的,所以,对于EnumMap来说,其所能存储的个数也就是固定的了。这种类型的Map相对来说是比较简单的。
二、主要实现介绍
1. 初始化
由于EnumMap的enum特点,决定了其容器的容量是不变的,所以,在创建一个EnumMap的时候,我们就需要指定其大小,目前创建一个EnumMap主要有以下几种方式:
public EnumMap(Class<K> keyType) : 根据键的class类型,通过反射的方式得到该枚举的所有可能值,进而生成一个键数组及值数组。
public EnumMap(EnumMap<K, ? extends V> m) :从另一个EnumMap去初始化,本质上是生成一个副本。
public EnumMap(Map<K, ? extends V> m):根据另一个Map初始化,和第二个方法相比,多了个对Map的转化的过程
以上三种初始化方式之后,在内部都会创建一个key数组和value数组,它们的大小是相同的。特别的,由于对同一类enum来说,其key是固定的,所以key数组是可以复用的。
2. 存储
我们来看一下对于put操作的实现
public V put(K key, V value) {
typeCheck(key);//类型检查 int index = key.ordinal();
Object oldValue = vals[index];
vals[index] = maskNull(value);//null值处理
if (oldValue == null)
size++;
return unmaskNull(oldValue);
}
可以看到整个实现非常简单,key对应的value被存储在vals数组中,key的ordinal对应的下标的位置。
需要注意的是,在存储时,系统对于值进行了maskNull的处理,在返回时做了unmaskNull处理,我们接着看下相关的代码:
private static final Object NULL = new Object() {
public int hashCode() {
return 0;
} public String toString() {
return "java.util.EnumMap.NULL";
}
}; private Object maskNull(Object value) {
return (value == null ? NULL : value);
} private V unmaskNull(Object value) {
return (V) (value == NULL ? null : value);
}
可以看到这个方法的作用是,如果目标value为null,则用NULL对象来替换,那么为什么要这样做呢?
这是因为,vals数组中,默认是没有值的,而这个用null来表示。那么,EnumMap本身是支持值为null的,如果不做任何处理将vals设置为null,则无法和没有值的情况进行区分,所以借助于这种方式来实现对于null值的表示。
3. 取值
和存值一样,取值也是比较简单的,如下:
public V get(Object key) {
return (isValidKey(key) ?
unmaskNull(vals[((Enum)key).ordinal()]) : null);
}
可见相比较于HashMap,这个取值操作是直接定位的,非常快速。
4. key存在判断
前面说到,初始化时实际上就已经确定了key的数组,那么,是否表示所有的key都存在呢?参见实现:
public boolean containsKey(Object key) {
return isValidKey(key) && vals[((Enum)key).ordinal()] != null;
}
可见,如果某个key对应的下标没有设置值,系统认为这个key是未被包含的。
三、总结
从前面的分析我们可以看到,EnumMap的实现非常简单,而且存取都非常高效,如果我们的业务场景是可以设置几个固定的key的值的话,那么用这类key将是非常高效的。
容器--EnumMap的更多相关文章
- Java集合容器简介
Java集合容器主要有以下几类: 1,内置容器:数组 2,list容器:Vetor,Stack,ArrayList,LinkedList, CopyOnWriteArrayList(1.5),Attr ...
- EnumMap源代码阅读器
EnumMap是一个用于存放键值为enum类型的map.全部的键值必须来自一个单一的enum类型.EnumMap内部用数组表示效率更高. EnumMap维持键值的自然顺序(即枚举类型常量声明的顺序), ...
- C++ Map 容器
1.Map是c++的一个标准容器,它提供了很好一对一的关系. Map是一种关联是容器,在map中增加和删除元素非常容易.可以修改一个特定的节点而不对其他节点不产生影响,由于map是一种关联式容器,Ke ...
- C++STL中map容器的说明和使用技巧(杂谈)
1.map简介 map是一类关联式容器.它的特点是增加和删除节点对迭代器的影响很小,除了那个操作节点,对其他的节点都没有什么影响.对于迭代器来说,可以修改实值,而不能修改key. 2.map的功能 自 ...
- 【38】java的集合框架(容器框架)
Collection接口 Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements).一些 Collection允许相同的元 ...
- java并发容器(Map、List、BlockingQueue)
转发: 大海巨浪 Java库本身就有多种线程安全的容器和同步工具,其中同步容器包括两部分:一个是Vector和Hashtable.另外还有JDK1.2中加入的同步包装类,这些类都是由Collectio ...
- java集合框架容器 java框架层级 继承图结构 集合框架的抽象类 集合框架主要实现类
本文关键词: java集合框架 框架设计理念 容器 继承层级结构 继承图 集合框架中的抽象类 主要的实现类 实现类特性 集合框架分类 集合框架并发包 并发实现类 什么是容器? 由一个或多个确 ...
- Java 容器 & 泛型:一、认识容器
Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket 容器是Java语言学习中重要的一部分.泥瓦匠我的感觉是刚开始挺难学的,但等你熟悉它,接触多了,也就“顺 ...
- Java容器-引用分类与部分Map用法
目录 1.引用分类 2.了解WeakHashMap.IdentityHashMap.EnumMap 3.同步控制与只读设置 代码实现 1.引用分类(面试) 强引用(StrongReference):引 ...
随机推荐
- Atitit 发帖机系列(7) 词法分析的方法attilax大总结)
Atitit 发帖机系列(7) 词法分析的方法attilax大总结) 1.1. 词法分析貌似俩大方法,一个直接根据状态图转换,一个根据dfa1 1.2. switchcase或者ifelse 最原始方 ...
- 大数据时代的IT架构设计
大数据时代的IT架构设计(来自互联网.银行等领域的一线架构师先进经验分享) IT架构设计研究组 编著 ISBN 978-7-121-22605-2 2014年4月出版 定价:49.00元 208页 ...
- C#设计模式-简单工厂
工厂模式专门负责将大量有共同接口的类实例化.工厂模式可以动态决定将哪一个类实例化,不必事先知道每次要实例化哪一个类.工厂模式有以下几种形态: 简单工厂(Simple Factory)模式 工厂方法(F ...
- 设置easyui input默认值
/*设置input 焦点*/ $(function () { //集体调用 $(".formTextBoxes input").each(function () { $(this) ...
- How Google TestsSoftware - The Life of a SET
SETs are Software Engineersin Test. They are software engineers who happen to write testing function ...
- 在忘记root密码的情况下如何修改linux系统的root密码
1.系统启动时长按shift键后可以看到如下界面: 2.找到 recovery mode 那一行, 按下[e]键进入命令编辑状态,到 linux /boot/vmlinuz-....... r ...
- Html与CSS快速入门01-基础概念
Web前端技术一直是自己的薄弱环节,经常为了调节一个简单的样式花费大量的时间.最近趁着在做前端部分的开发,果断把这部分知识成体系的恶补一下.内容相对都比较简单,很类似工具手册的学习,但目标是熟练掌握. ...
- JSP网站开发基础总结《十》
经过上一篇的介绍相信大家对JSP提供的过滤器一定有了一个概念,本篇我们就一起再来研究一下关于创建多个过滤器时,如果有两个以上过滤器的过滤规则相同,那么这些过滤器的执行顺序如何呢?答案是根据我们在web ...
- Docker 有什么优势?
1.什么是容器? 依托与linux 内核功能的虚拟化技术 2. docker 是什么? 能够把应用程序自动部署到容器的开源引擎 3. docker 跟原有的工具有何区别? 传统的部署模式是:安装(包管 ...
- linux分享六:进程管理
1:批量杀死进程 ps -ef|grep LOCAL=NO|grep -v grep|cut -c 9-15|xargs kill -9 或kill -9 `ps -ef|grep oracle|aw ...