EnumMap的用法和源码解析
EnumMap的用法:
EnumMap顾名思义是保存枚举类型的Map.它要求map的key是枚举类型。这点在类定义的时候就已经声明好了EnumMap<K extends Enum<K>, V>,如何不是枚举类型编译会出错。
eg:定义了一个Enum类 JdbcType。
public enum JdbcType {
INT,NUMBER,VARCHAR,VARCHAR2,LONG,BLOB,CHAR;
}
--------------------------------------------EnumMap的一个简单应用-----------------------------------------------
public class EnumMapTest {
public static void main(String[] args) {
EnumMap<JdbcType, String> enumMap=new EnumMap<JdbcType, String>(JdbcType.class);
enumMap.put(JdbcType.INT, "INT TYPE");
enumMap.put(JdbcType.NUMBER, "NUMBER TYPE");
enumMap.put(null,"NULL ");
System.out.println(enumMap.get(JdbcType.INT));
}
}
EnumMap的有什么优点,为什么我们要用EnumMap。
.1 相比HashMap,EnumMap的性能和速度要快的多。EnumMap里面的数据结构是数组,获取的数据的时候特别快。而且添加的数据的时候(一般用put(K,V)),这里面的并不像一般数组一样,当插入到中间的位置时候,要数组整体移动(一般实现依次向后移动)。EnumMap实现不需要,因为数组在EnumMap实例化的时候就已经初始化好了,要做的就是对原来的oldValue进行覆盖,这样无论获取数据还是添加和删除数据都要快的多。这里特别提示一下,为什么EnumMap能够用数组,这得益于EnumMap的key是枚举类型,枚举类类型中每一种类型,在声明的时候都有确定的位置,可以通过对应的位置确定的枚举类型。通过该方法获得位置key.ordinal();
2.枚举类型的相应的类型更加明确,key对应的范围更加明确。列如的key是string,那么你的键范围无法确定。所以能够用EnumMap,尽量用EnumMap这也是一种代码优化方案’
EnumMap的大量用到各种框架中,在Mabatis的TypeHandlerRegistry中就用到了EnumMap:
public final class TypeHandlerRegistry {
private final Map<JdbcType, TypeHandler<?>> JDBC_TYPE_HANDLER_MAP = new EnumMap<JdbcType, TypeHandler<?>>(JdbcType.class);
有兴趣的同学可以去看看TypeHandlerRegistry源码,会对EnumMap理解更加透彻。
下面对EnumMap源码进行解析:
public EnumMap(Class<K> keyType) { //EnumMap的构造器 keyType是key的类型,只能是枚举类型,否则不能编译过去
this.keyType = keyType;
keyUniverse = getKeyUniverse(keyType);//getKeyUniverse方面获得该枚举中所有类型,返回一个数组该枚举类型中所有实例
vals = new Object[keyUniverse.length];//初始化该数组,该数组大小不会改变,因为枚举类型确定了,相同的键会进行值的覆盖,该数组也是map底层的数据结构
}
新增方法:
public V put(K key, V value) {
typeCheck(key); //类型检查,只有该enum类型才能,进行数据录入。实际开发中null值可以编译通过,但是到这步检查会报空指针。
int index = key.ordinal();//获取改值在enum中的声明的位置,通过该位置定位该值
Object oldValue = vals[index];
vals[index] = maskNull(value);
if (oldValue == null) //oldNull为null为新增,oldNull有值进行覆盖
size++;
return unmaskNull(oldValue);
}
该方法 的用法API说的很清楚了:
Associates the specified value with the specified key in this map.
If the map previously contained a mapping for this key, the old
value is replaced.
删除方法:
public V remove(Object key) {
if (!isValidKey(key)) // 如何该key是null,或者不是初始化时enum类型,直接返回null,不进行删除操作
return null;
int index = ((Enum<?>)key).ordinal(); //获取该值的位置,也是在数组中位置
Object oldValue = vals[index]; //定位该值
vals[index] = null; //对该值赋值null,也就是常见的逻辑删除,故删除速度也很快,不进行数组移动,定位之后,进行赋值操作
if (oldValue != null) //原来有值对数组大小进行-1操作,否则不操作。
size--;
return unmaskNull(oldValue);
}
get值方法:该方法很简单不做解释:
public V get(Object key) {
return (isValidKey(key) ?
unmaskNull(vals[((Enum<?>)key).ordinal()]) : null);
}
EnumMap源码就解析到这里了,感兴趣的同学可以自己看看。
转载于:https://www.cnblogs.com/caibixiang123/p/9214086.html
EnumMap的用法和源码解析相关推荐
- 状态模式的介绍及状态机模型的函数库javascript-state-machine的用法和源码解析
文章大体就两部分: 状态模式 状态机模型的函数库javascript-state-machine的用法和源码解析 场景及问题背景: 我们平时开发时本质上就是对应用程序的各种状态进行切换并作出相应处理. ...
- CountDownLatch 用法和源码解析
CountDownLatch 是多线程控制的一种工具,它被称为 门阀. 计数器或者 闭锁.这个工具经常用来用来协调多个线程之间的同步,或者说起到线程之间的通信(而不是用作互斥的作用).下面我们就来一起 ...
- Google Test(GTest)使用方法和源码解析——模板类测试技术分析和应用
写C++难免会遇到模板问题,如果要针对一个模板类进行测试,似乎之前博文中介绍的方式只能傻乎乎的一个一个特化类型后再进行测试.其实GTest提供了两种测试模板类的方法,本文我们将介绍方法的使用,并分析其 ...
- Google Test(GTest)使用方法和源码解析——参数自动填充技术分析和应用
在我们设计测试用例时,我们需要考虑很多场景.每个场景都可能要细致地考虑到到各个参数的选择.比如我们希望使用函数IsPrime检测10000以内字的数字,难道我们要写一万行代码么?(转载请指明出于bre ...
- Google Test(GTest)使用方法和源码解析——私有属性代码测试技术分析
有些时候,我们不仅要测试类暴露出来的公有方法,还要测试其受保护的或者私有方法.GTest测试框架提供了一种方法,让我们可以测试类的私有方法.但是这是一种侵入式的,会破坏原来代码的结构,所以我觉得还是谨 ...
- Google Test(GTest)使用方法和源码解析——预处理技术分析和应用
预处理 在<Google Test(GTest)使用方法和源码解析--概况>最后一部分,我们介绍了GTest的预处理特性.现在我们就详细介绍该特性的使用和相关源码.(转载请指明出于brea ...
- Google Test(GTest)使用方法和源码解析——断言的使用方法和解析
在之前博文的基础上,我们将介绍部分断言的使用,同时穿插一些源码.(转载请指明出于breaksoftware的csdn博客) 断言(Assertions) 断言是GTest局部测试中最简单的使用方法,我 ...
- Google Test(GTest)使用方法和源码解析——Listener技术分析和应用
在<Google Test(GTest)使用方法和源码解析--结果统计机制分析>文中,我么分析了GTest如何对测试结果进行统计的.本文我们将解析其结果输出所使用到的Listener机制. ...
- Google Test(GTest)使用方法和源码解析——结果统计机制分析
在分析源码之前,我们先看一个例子.以<Google Test(GTest)使用方法和源码解析--概况 >一文中最后一个实例代码为基准,修改最后一个"局部测试"结果为错误 ...
最新文章
- 办公求生指南:分享10个可以提高办公效率的优质神器
- JDBC的两种sql命令发送器比较【Statement:PreparedStatement】
- React16.2的fiber架构
- Python--三元表达式、列表推导式、生成器表达式、递归、匿名函数、内置函数...
- AI算法连载12:统计之梯度提升树
- SAP License:统计型实际结算型内部订单
- stdmove 跟 左键引用 区别_C++ auto和decltype的区别
- WPF 与 摄像头资料
- Ubuntu20.04环境下 安装Tensorflow
- Mybatis之select元素
- 神经网络训练样本的标签,训练图像识别神经网络
- 牛客网C语言题目练习
- 42. OP-TEE中secure stroage------安全文件的创建
- Pandas入门基本知识点
- JAVA校招基础面试题
- 【WB32库开发】第12章(上)TIM1高级定时器——PWM输入捕获
- 深入分布式缓存:微博是如何应对日访问量百亿级的缓存架构设计
- 大数据架构师之路究竟是如何养成的?来看看技术大佬的经验之谈吧!
- 2023计算机毕业设计SSM最新选题之java交通违章举报平台lxsqm
- Golang练手小项目系列