HashMap的数据结构:

在java编程语言中,最基本的结构就是两种,一个是数组,另外一个是模拟指针(引用),所有的数据结构都可以用这两个基本结构来构造的,HashMap也不例外。HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。

从上图中可以看出,HashMap底层就是一个数组结构,数组中的每一项又是一个链表。当新建一个HashMap的时候,就会初始化一个数组。

1.HashMap的存取实现:

当我们往HashMap中put元素的时候,先根据key的hashCode重新计算hash值,根据hash值得到这个元素在数组中的位置(即下标),如果数组该位置上已经存放有其他元素了,那么在这个位置上的元素将以链表的形式存放,新加入的放在链头,最先加入的放在链尾。如果数组该位置上没有元素,就直接将该元素放到此数组中的该位置上。

我们可以看到在HashMap中要找到某个元素,需要根据key的hash值来求得对应数组中的位置。如何计算这个位置就是hash算法。前面说过HashMap的数据结构是数组和链表的结合,所以我们当然希望这个HashMap里面的元素位置尽量的分布均匀些,尽量使得每个位置上的元素数量只有一个,那么当我们用hash算法求得这个位置的时候,马上就可以知道对应位置的元素就是我们要的,而不用再去遍历链表,这样就大大优化了查询的效率。

对于任意给定的对象,只要它的 hashCode()返回值相同,那么程序调用 hash(int h) 方法所计算得到的hash 码值总是相同的。我们首先想到的就是把hash值对数组长度取模运算,这样一来,元素的分布相对来说是比较均匀的。但是,“模”运算的消耗还是比较大的,在HashMap中是这样做的:调用 indexFor(int h, int length) 方法来计算该对象应该保存在 table 数组的哪个索引处。

2读取:

从HashMap中get元素时,首先计算key的hashCode,找到数组中对应位置的某一元素,然后通过key的equals方法在对应位置的链表中找到需要的元素。

归纳起来简单地说,HashMap 在底层将 key-value 当成一个整体进行处理,这个整体就是一个 Entry对象。HashMap 底层采用一个 Entry[] 数组来保存所有的 key-value 对,当需要存储一个 Entry 对象时,会根据hash算法来决定其在数组中的存储位置,在根据equals方法决定其在该数组位置上的链表中的存储位置;当需要取出一个Entry时,也会根据hash算法找到其在数组中的存储位置,再根据equals方法从该位置上的链表中取出该Entry。

3.    HashMap的resize(rehash):

当HashMap中的元素越来越多的时候,hash冲突的几率也就越来越高,因为数组的长度是固定的。所以为了提高查询的效率,就要对HashMap的数组进行扩容,数组扩容这个操作也会出现在ArrayList中,这是一个常用的操作,而在HashMap数组扩容之后,最消耗性能的点就出现了:原数组中的数据必须重新计算其在新数组中的位置,并放进去,这就是resize。

那么HashMap什么时候进行扩容呢?当HashMap中的元素个数超过数组大小*loadFactor时,就会进行数组扩容,loadFactor的默认值为0.75,这是一个折中的取值。也就是说,默认情况下,数组大小为16,那么当HashMap中元素个数超过16*0.75=12的时候,就把数组的大小扩展为 2*16=32,即扩大一倍,然后重新计算每个元素在数组中的位置,而这是一个非常消耗性能的操作,所以如果我们已经预知HashMap中元素的个数,那么预设元素的个数能够有效的提高HashMap的性能。

出处:http://blog.csdn.net

java HashMap的原理的更多相关文章

  1. Java HashMap工作原理及实现

    Java HashMap工作原理及实现 2016/03/20 | 分类: 基础技术 | 0 条评论 | 标签: HASHMAP 分享到:3 原文出处: Yikun 1. 概述 从本文你可以学习到: 什 ...

  2. Java HashMap实现原理 源码剖析

    HashMap是基于哈希表的Map接口实现,提供了所有可选的映射操作,并允许使用null值和null建,不同步且不保证映射顺序.下面记录一下研究HashMap实现原理. HashMap内部存储 在Ha ...

  3. [翻译]Java HashMap工作原理

    大部分Java开发者都在使用Map,特别是HashMap.HashMap是一种简单但强大的方式去存储和获取数据.但有多少开发者知道HashMap内部如何工作呢?几天前,我阅读了java.util.Ha ...

  4. 【转】Java HashMap工作原理(好文章)

    大部分Java开发者都在使用Map,特别是HashMap.HashMap是一种简单但强大的方式去存储和获取数据.但有多少开发者知道HashMap内部如何工作呢?几天前,我阅读了java.util.Ha ...

  5. Java HashMap工作原理深入探讨

    大部分Java开发者都在使用Map,特别是HashMap.HashMap是一种简单但强大的方式去存储和获取数据.但有多少开发者知道HashMap内部如何工作呢?几天前,我阅读了java.util.Ha ...

  6. Java HashMap工作原理及实现[转]

    原文:http://yikun.github.io/2015/04/01/Java-HashMap%E5%B7%A5%E4%BD%9C%E5%8E%9F%E7%90%86%E5%8F%8A%E5%AE ...

  7. 160706、Java HashMap工作原理及实现

    1. 概述 从本文你可以学习到: 什么时候会使用HashMap?他有什么特点? 你知道HashMap的工作原理吗? 你知道get和put的原理吗?equals()和hashCode()的都有什么作用? ...

  8. Java HashMap实现原理分析

    参考链接:https://www.cnblogs.com/xiarongjin/p/8310011.html 1. HashMap的数据结构 数据结构中有数组和链表来实现对数据的存储,但这两者基本上是 ...

  9. Java HashMap工作原理:不仅仅是HashMap

    前言: 几乎所有java程序员都用过hashMap,但会用不一定会说. 近年来hashMap是非常常见的面试题,如何为自己的回答加分?需要从理解开始. "你用过hashMap吗?" ...

随机推荐

  1. android开发架构理解

    1. android 开发和普通的PC程序开发的,我觉得还是不要过度设计,因为手机开发,项目相对传统软件开发就小很多,而且手机的性能有限,过度设计代码mapping需要消耗的能相对就高,而且手机开发的 ...

  2. js中substring/substr和C#中Substring的用法

    一:在js中截取字符串的方法有两个:substring和substr 1.方法: substring(int stringIndex,[int endIndex]) 截取从索引为stringIndex ...

  3. Matlab 取子矩阵

    MATLAB如何提取矩阵的子块 在matlab中如何提取一个矩阵的部分元素 1.提取大矩阵的一列.一行元素: 一列元素:  A(:,j)表示提取A矩阵的第j列全部元素 一行元素:  A(i,:)表示提 ...

  4. javascript:Array.slice.call 到Array.prototype.slice.call

    举个从对象到数组的例子: var obj={}; obj[1]=1; obj[2]=2; obj.length=2; var arr =Array.prototype.slice.call(obj); ...

  5. 安卓网络请求之——OkHttp学习

    之前做安卓项目的时候,HTTP请求用的是android api中的HttpURLConnection和HttpClient,编码比较繁琐,自己封装的也不好.后来知道有很多网络请求的第三方框架,可以方便 ...

  6. 必须声明标量变量 "@cid"。

    出错代码: public bool Delete_List(int cID) { StringBuilder strSql = new StringBuilder(); strSql.Append(& ...

  7. awk的日志模块追加日期时间字段的方案

    function test() { i = ) { system("sleep 1") "date +'%Y-%m-%d %H:%M:%S'" | getlin ...

  8. cf C. Insertion Sort

    http://codeforces.com/contest/362/problem/C #include <cstdio> #include <cstring> #includ ...

  9. ASP.NET页面事件顺序

    当一个页面请求发送到WEB服务器时,不论该事件是由页面提交还是由页面重定向而激发的,页面在其被创建到释放的过程中都会运行一系列的事件.一个ASP.NET页面从悲怆见到释放的过程包含10个事件. (1) ...

  10. 玩Linux桌面发现一个最佳的组合配置

    其实前段时间玩Arch,其实不难,主要是太浪费时间配置折腾了,学到有用的东西太少,不能让我快速进入编程工作的状态,(真不知道有些人用Gentoo和Arch都能用出优越感了,就因为难安装和配置??)但是 ...