HashMap原理剖析

  之前有看过别人的HashMap源代码的分析,今天尝试自己来分析一波,纯属个人愚见。听一些老的程序员说过,当别人跟你说用某样技术到项目中去,而你按照别人的想法实现了的时候,你只能是一个码农,当你自己会想到用一样东西到你的实际开发中的时候,你是一个普通的程序员,当你不仅能想到用某样技术到项目中去,而且深深的熟悉这项技术的底层实现,那就是一个有内功的程序员了。

  HashMap,哈希表,基于哈希算法实现的一个java集合。起初使用这个哈希表的时候,感觉非常的不习惯,主要是容易和其他的几种哈希表搞混,就当时的理解来说,哪个哈希表的键不能为空,哪个哈希表的值可以为空等等,觉得这些东西记住了就感觉自己非常的牛逼了。但是随着学习的进一步深入,总会有疑问,哈希表到底是如何实现的?那就按照api的方法来一个一个解释。

构造方法:

1.空参数的构造方法

      public HashMap() {
//初始化加载因子,等于默认的加载因子0.75
this.loadFactor = DEFAULT_LOAD_FACTOR;
//最大容量为初始化容量乘以加载因子
threshold = (int)(DEFAULT_INITIAL_CAPACITY * DEFAULT_LOAD_FACTOR);
//初始化一个长度为16的entry数组,也就是存放键值对的数组
table = new Entry[DEFAULT_INITIAL_CAPACITY];
//调用init方法
init();
}

2.初始化容量的构造方法

 public HashMap(int initialCapacity) {
//调用两个参数的构造方法,初始化容量和默认加载因子
this(initialCapacity, DEFAULT_LOAD_FACTOR);
}

3.初始化容器和初始化加载因子的构造方法

public HashMap(int initialCapacity, float loadFactor) {
if (initialCapacity < 0)
throw new IllegalArgumentException("Illegal initial capacity: " +
initialCapacity);
if (initialCapacity > MAXIMUM_CAPACITY)
initialCapacity = MAXIMUM_CAPACITY;
if (loadFactor <= 0 || Float.isNaN(loadFactor))
throw new IllegalArgumentException("Illegal load factor: " +
loadFactor); int capacity = 1;
while (capacity < initialCapacity)
capacity <<= 1; this.loadFactor = loadFactor;
threshold = (int)(capacity * loadFactor);
table = new Entry[capacity];
init();
}

4.Map集合作为参数的构造方法

 public HashMap(Map<? extends K, ? extends V> m) {
//调用初始化加载因子和初始化容量两个参数的构造方法
this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1,
DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR);
//将参数Map中的key-value对放入新创建的map集合中
putAllForCreate(m);
}

存放键值对的方法:

 public V put(K key, V value) {
//如果key为空,则调用放入null key的方法,占用entry数组的一个位置
if (key == null)
return putForNullKey(value);
//根据key值计算出hash码值
int hash = hash(key.hashCode());
//并根据哈希码的值计算出该key-value在entry数组中的存放位置
int i = indexFor(hash, table.length);
//根据索引直接定位到那个元素并且从那个元素开始遍历
for (Entry<K,V> e = table[i]; e != null; e = e.next) {
Object k;
if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
V oldValue = e.value;
e.value = value;
e.recordAccess(this);
return oldValue;
}
} modCount++;//修改次数加1
addEntry(hash, key, value, i);//将key-value对添加进入entry数组
return null;
}

HashMap源代码解析的更多相关文章

  1. Android xUtils3源代码解析之网络模块

    本文已授权微信公众号<非著名程序猿>原创首发,转载请务必注明出处. xUtils3源代码解析系列 一. Android xUtils3源代码解析之网络模块 二. Android xUtil ...

  2. android7.x Launcher3源代码解析(3)---workspace和allapps载入流程

    Launcher系列目录: 一.android7.x Launcher3源代码解析(1)-启动流程 二.android7.x Launcher3源代码解析(2)-框架结构 三.android7.x L ...

  3. 使用具体解释及源代码解析Android中的Adapter、BaseAdapter、ArrayAdapter、SimpleAdapter和SimpleCursorAdapter

    Adapter相当于一个数据源,能够给AdapterView提供数据.并依据数据创建相应的UI.能够通过调用AdapterView的setAdapter方法使得AdapterView将Adapter作 ...

  4. Spring源代码解析

    Spring源代码解析(一):IOC容器:http://www.iteye.com/topic/86339 Spring源代码解析(二):IoC容器在Web容器中的启动:http://www.itey ...

  5. java集合框架之java HashMap代码解析

     java集合框架之java HashMap代码解析 文章Java集合框架综述后,具体集合类的代码,首先以既熟悉又陌生的HashMap开始. 源自http://www.codeceo.com/arti ...

  6. Arrays.sort源代码解析

    Java Arrays.sort源代码解析 Java Arrays中提供了对所有类型的排序.其中主要分为Primitive(8种基本类型)和Object两大类. 基本类型:采用调优的快速排序: 对象类 ...

  7. Spring源代码解析(收藏)

    Spring源代码解析(收藏)   Spring源代码解析(一):IOC容器:http://www.iteye.com/topic/86339 Spring源代码解析(二):IoC容器在Web容器中的 ...

  8. volley源代码解析(七)--终于目的之Response&lt;T&gt;

    在上篇文章中,我们终于通过网络,获取到了HttpResponse对象 HttpResponse是android包里面的一个类.然后为了更高的扩展性,我们在BasicNetwork类里面看到.Volle ...

  9. Cocos2d-x源代码解析(1)——地图模块(3)

    接上一章<Cocos2d-x源代码解析(1)--地图模块(2)> 通过前面两章的分析,我们能够知道cocos将tmx的信息结构化到 CCTMXMapInfo.CCTMXTilesetInf ...

随机推荐

  1. JAVA泛型——基本使用

    Java1.5版本推出了泛型,虽然这层语法糖给开发人员带来了代码复用性方面的提升,但是这不过是编译器所做的一层语法糖,在真正生成的字节码中,这类信息却被擦除了.笔者发现很多几年开发经验的程序员,依然不 ...

  2. PL/SQL之存储过程和函数

    1.创建存储过程 .1语法: CREATE[OR REPLACE] PROCEDURE [schema.] procedure_name[(argument[{IN|OUT|IN OUT}] data ...

  3. Odata简介和Demo

    转:http://www.cnblogs.com/shanyou/archive/2013/06/11/3131583.html 在SOA的世界中,最重要的一个概念就是契约(contract).在云计 ...

  4. jquery 获取 tagName(JQuery如何得到tagName?)

    在javascript中要取得tagName十分简单,但在jQuery中官方文档却没有记载,在一通百度和谷歌之后,尝试了不少所谓秘技,都不能正确得到,经过自己的验证,终于找到了方法,于是记录下来以备忘 ...

  5. C# System.Timers.Timers的用法在工控设备上位中的用法

    这两天写设备的上位,由于要读取服务器上的数据库,通过WEBSERVICE访问数据库,我具体的做法是: 1.专门用Timer起线程执行,由于在用的时候报错,不能访问其他线程资源的错误,因此我用了委托的方 ...

  6. 十二、异步工具Timer

    一.简介 JDK提供一种异步线程工具Timer类,你可以利用这个类做延迟任务.周期性任务等. JDK文档:http://tool.oschina.net/uploads/apidocs/jdk-zh/ ...

  7. IO实战-RandomAccessFile在本地实现伪断点续传

    准备:在磁盘中 准备一个目录文件 实现:将该文件复制到目标路径中,关掉程序,再重新打开可以在原位置继续复制. 需求如下: 过程中显示文件的拷贝的百分比 复制过程中关掉程序. 重新启动该程序时,若上次没 ...

  8. laravel之注册中间件

    1.添加中间件的命令:php artisan make:middleware 中间件名称 2.给中间件指定key值:在kernel.php中 3.在中间件中添加逻辑代码

  9. jquery操作select(选中,取值)

    最近工作中总出现select 和 option问题,整理一下,内容大部分源于网络资料 一.基础取值问题 例如<select class="selector"></ ...

  10. LeetCode算法题5----Longest Palindromic Substring

    #5. Longest Palindromic Substring Given a string S, find the longest palindromic substring in S. You ...