一、概述

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的更多相关文章

  1. Java集合容器简介

    Java集合容器主要有以下几类: 1,内置容器:数组 2,list容器:Vetor,Stack,ArrayList,LinkedList, CopyOnWriteArrayList(1.5),Attr ...

  2. EnumMap源代码阅读器

    EnumMap是一个用于存放键值为enum类型的map.全部的键值必须来自一个单一的enum类型.EnumMap内部用数组表示效率更高. EnumMap维持键值的自然顺序(即枚举类型常量声明的顺序), ...

  3. C++ Map 容器

    1.Map是c++的一个标准容器,它提供了很好一对一的关系. Map是一种关联是容器,在map中增加和删除元素非常容易.可以修改一个特定的节点而不对其他节点不产生影响,由于map是一种关联式容器,Ke ...

  4. C++STL中map容器的说明和使用技巧(杂谈)

    1.map简介 map是一类关联式容器.它的特点是增加和删除节点对迭代器的影响很小,除了那个操作节点,对其他的节点都没有什么影响.对于迭代器来说,可以修改实值,而不能修改key. 2.map的功能 自 ...

  5. 【38】java的集合框架(容器框架)

    Collection接口 Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements).一些 Collection允许相同的元 ...

  6. java并发容器(Map、List、BlockingQueue)

    转发: 大海巨浪 Java库本身就有多种线程安全的容器和同步工具,其中同步容器包括两部分:一个是Vector和Hashtable.另外还有JDK1.2中加入的同步包装类,这些类都是由Collectio ...

  7. java集合框架容器 java框架层级 继承图结构 集合框架的抽象类 集合框架主要实现类

    本文关键词: java集合框架  框架设计理念  容器 继承层级结构 继承图 集合框架中的抽象类  主要的实现类 实现类特性   集合框架分类 集合框架并发包 并发实现类 什么是容器? 由一个或多个确 ...

  8. Java 容器 & 泛型:一、认识容器

    Writer:BYSocket(泥沙砖瓦浆木匠) 微博:BYSocket 豆瓣:BYSocket 容器是Java语言学习中重要的一部分.泥瓦匠我的感觉是刚开始挺难学的,但等你熟悉它,接触多了,也就“顺 ...

  9. Java容器-引用分类与部分Map用法

    目录 1.引用分类 2.了解WeakHashMap.IdentityHashMap.EnumMap 3.同步控制与只读设置 代码实现 1.引用分类(面试) 强引用(StrongReference):引 ...

随机推荐

  1. Atitit.加密算法ati Aes的框架设计v2.2

    Atitit.加密算法ati Aes的框架设计v2.2 版本进化1 V2.2   add def decode key api1 v1版本1 Aes的历史2 Atitit.加密算法 des  aes  ...

  2. Atitit. Api 设计 原则 ---归一化

    Atitit. Api 设计 原则 ---归一化 1.1. 叫做归一化1 1.2. 归一化的实例:一切对象都可以序列化/toString  通过接口实现1 1.3. 泛文件概念.2 1.4. 游戏行业 ...

  3. [java] 找出字符串中出现最多的字符和出现的次数

    逛园子看到一童鞋做的华为上机题目,写来好长的代码,懒得看,感觉不可能这么难,于是动手敲了下. import java.util.Scanner; public class StringTest { / ...

  4. 引入CSS文件的@import与link的权重分析

    我很少在CSS用到@import这个标签,最近看到一句话“link方式的样式的权重 高于@import的权重”,感觉不太对,@import只是一个引入外部文件而已,怎么会有高于link的权重呢?于是我 ...

  5. c++实现kd树

    #ifndef _KD_TREE_H_ #define _KD_TREE_H_ #include <memory> #include <vector> #include < ...

  6. JAVA设计模式《四》

    经过前几篇的介绍相信大家对JAVA的设计模式一定有所解了,本篇我们再一起学习一下适配器模式.代理模式和工厂模式. 适配器模式使用的场景非常多,例如现实生活中,我们的笔记本电脑的充电线大部分都是三向插头 ...

  7. bootstrap-datetimepicker.js学习

    之前项目运用到了这个时间控件,期间bug还是一些.抽个时间,简单地看一下. 先看一下datetimepicker.js的结构 var DateTimePicker = function(element ...

  8. 【web前端面试题整理05】做几道前端面试题休息休息吧

    前言 连续学了两天javascript的东西了,我们都累了,于是今天还是上一套面试题吧,大家一起休息休息,也为下个星期可能会有的面试准备下. 题目一览 CSS1.  overflow-x  属于 CS ...

  9. 30套免费的响应式 HTML5 & CSS3 模板下载

    HTML5 和 CSS3 网站模板存在巨大的需求,网页设计师们都喜欢现成的网站模板,能够轻松地设计和开发美观,吸引眼球的网站.如果你正在寻找响应式的 HTML5 & CSS3 模板,那么你找对 ...

  10. 如何禁用事件的浮升(div的子元素的点击事件会触发父元素的点击事件)

    <div onclick="alert();"> <div onclick="alert();"></div> </d ...