一、概述

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. javascript中可变值与不可变值(原始值)

    字符串原始值修改不了1 var str = "abc"; 2 str[0] = "d"; 3 console.log(str[1]="f") ...

  2. Oracle 11g系列:数据表对象

    Oracle数据库的下一层逻辑结构并非数据表,而是表空间.每个数据表都属于唯一的表空间. 1.Oracle表空间 与数据表相同,Oracle表空间是一个逻辑对象,而非物理对象,是数据库的组成部分.当使 ...

  3. java session 详解

    原网址:http://blog.sina.com.cn/s/blog_670b6d880101deff.html 一.术语session 在我的经验里,session这个词被滥用的程度大概仅次于tra ...

  4. poj 1724ROADS(bfs和dfs做法)

    /* dfs比较好想,就是测试数据的问题,导致在遍历边的时候要倒着遍历才过! */ #include<iostream> #include<cstdio> #include&l ...

  5. 苹果官方发布,iPhone 6 & Plus 设计素材

    苹果发布 iPhone 6 和 iPhone 6 Plus 有一段时间了,据说首日预定量达到了创纪录的1600万部,真是不可思议.苹果已经创建了一些指引,让开发者可以受益.他们已经发布了一组苹果官方的 ...

  6. Android 2.x中使用actionbar - Actionbarsherlock

    1. 范例说明 从Android 3.0开始,Android引入了ActoinBar,不得不说3.0之前android的标题栏确实比较丑,并且还没有任何功能. 之前很多应用的顶部栏很多都是仿苹果的,比 ...

  7. Windows Azure Virtual Machine (31) 迁移Azure虚拟机

    <Windows Azure Platform 系列文章目录> 为什么要写这篇Blog? 之前遇到过很多客户提问: (1)我之前创建的虚拟机,没有加入虚拟网络.现在需要重新加入虚拟机网络, ...

  8. 从.net转型,聊聊最近一些面试,薪资和想法

    上一个星期,一篇名为<.net估计要写在你手里了>几乎点燃了整个园子,有人群情激愤了,有人点赞的,有人上去打算喷博主个体无完肤的,总之,这篇博客很成功的引起一些.net 从业者的思考,也包 ...

  9. Android事件分发机制理解

    预备知识 触摸事件 : 安卓中把触摸事件封装成了一个类MotionEvent,用户的一次点击.触摸或者滑动都会产生一系列的MotionEvent 这个类的内容很简单,就两个东西:事件类型+坐标xy 事 ...

  10. 抓取代理IP

    写脚本从指定网站抓取数据的时候,免不了会被网站屏蔽IP.所以呢,就需要有一些IP代理.随便在网上找了一个提供免费IP的网站西刺做IP抓取.本次实践抓取的是其提供的国内匿名代理.可以打开网站查看一下源码 ...