HashMap的工作原理及性能分析

HashMap
	HashMap的工作原理:
	HashMap是基于hash算法的原理,使用put(key, value)方法来存储对象,使用get(key)方法来获取对象。

		1,当我们使用put()方法时,需要给它传递一个键值对,然后它调用键的hashCode()方法,返回的hashCode用于找到对应的bucket的位置(即table的下标)来储存Entry对象。
		如果该key对应的键值对已经存在,则用新的value取代旧的value;返回了旧的value后,直接退出。
		如果key为null,则将该键值对添加到table[0]中。
		注:
			1)当两个entry对象(一个是要新添加进来的对象,一个是已经存在的对象)的Key不同,而entry对象的hash值相同时,就会发生碰撞。HashMap使用链表存储对象,会把新添加的键值对存储在链表头部。

			2)当HashMap中entry数组的实际大小(已放入entry的数量) 大于或等于阈值threshold(threshold = 容量*加载因子loadFactor)时,则
			将会创建一个是原来entry数组(即table)大小两倍的entry数组,并将原来的entry对象放入新的entry数组中。这个过程叫作rehashing,因为它调用hash方法找到新的bucket位置(即table的下标)

			3)在多线程环境下使用HashMap可能导致死锁:
			如果两个线程都发现HashMap需要重新调整大小了,它们可能会同时试着调整大小。如果条件竞争发生了,那么就死循环了。
			在调整大小的过程中,存储在链表中的元素的次序会反过来,因为移动到新的bucket位置的时候,HashMap并不会将元素依次放在链表的尾部,而是依次放在头部,这是为了避免尾部遍历(tail traversing)。
			故在多线程环境下应该使用ConcurrentHashMap或HashTable

		2,当我们使用get()方法时,需要给它传递一个Key,然后它调用Key的hashCode()方法,返回的hashCode用于找到对应的bucket的位置(即table的下标),然后返回该位置上 hash值和key值均相等 的entry的value值。
		如果传递的Key为null,则返回table[0]中key为null的entry的value值。如果没有找到,则返回null。
		注:
			1)当两个entry对象(一个是要新添加进来的对象,一个是已经存在的对象)的Key不同,而entry对象的hash值相同时,就会发生碰撞。此时,会调用key.equals()方法去找到链表中正确的entry对象的value值

	HashMap性能:
	1)使用String、Interger等包装类适合作为键:
		String、Interger等包装类是final修饰的类,并且重写了equals()和hashCode()方法。
		1,因为要计算键的hashCode,就必须保证键的值不会改变。如果一个键的值在放入时的hashcode和获取时的hashcode不同的话,那么就不能从HashMap中找到正确的entry对象。
		2,键对象正确地重写equals()和hashCode()方法是非常重要的。hashCode()方法应尽量使两个不相等的对象返回不同的hashcode,那么碰撞的几率就会小些,这样HashMap的性能就能提高些。
		   说明:当每个bucket里存储的Entry只是单个Entry ———— 也就是没有通过指针产生Entry链时,此时的 HashMap 具有最好的性能
		3,键的不可变性使得程序能够缓存不同键的hashcode,这将提高整个获取对象的速度,故HashMap的性能也可提高些。
		4,String最常用
		5,键的不可变性也相应地提高了线程安全。

	2)加载因子的大小很重要
		1,加载因子越大,对空间的利用越充分,但是查找的效率会降低(链表长度会越来越长);
		2,加载因子太小,那么表中的数据将过于稀疏(很多空间还没用,就开始扩容了),对空间造成严重浪费。
		3,系统默认加载因子为0.75,这是一个比较理想的值,一般情况下我们是无需修改的。

	3)HashMap中则通过h&(length-1)的方法来代替取模,同样实现了均匀的散列,但效率要高很多。
		哈希表的容量(entry数组的length)必须是2的整数次幂的原因:
			1,length为2的整数次幂的话,h&(length-1)就相当于对length取模,这样便保证了散列的均匀,同时也提升了效率;
			2,length为2的整数次幂的话,为偶数,这样length-1为奇数,奇数的最后一位是1,这样便保证了h&(length-1)的最后一位可能为0,也可能为1(这取决于hash值),即:与后的结果可能为偶数,也可能为奇数,这样便保证了散列的均匀性。
			3,如果length为奇数的话,很明显length-1为偶数,它的最后一位是0,这样h&(length-1)的最后一位肯定为0,即只能为偶数,这样任何hash值都只会被散列到数组的偶数下标位置上,这便浪费了近一半的空间。
时间: 2024-08-02 23:58:09

HashMap的工作原理及性能分析的相关文章

HashMap的工作原理

这是一节让你深入理解hash_map的介绍,如果你只是想囫囵吞枣,不想理解其原理,你倒是可以略过这一节,但我还是建议你看看,多了解一些没有坏处. hash_map基于hash table(哈希表).哈希表最大的优点,就是把数据的存储和查找消耗的时间大大降低,几乎可以看成是常数时间:而代价仅仅是消耗比较多的内存.然而在当前可利用内存越来越多的情况下,用空间换时间的做法是值得的.另外,编码比较容易也是它的特点之一. 其基本原理是:使用一个下标范围比较大的数组来存储元素.可以设计一个函数(哈希函数,也

从头认识java-15.7 Map(2)-介绍HashMap的工作原理-put方法

这一章节我们来介绍HashMap的工作原理. 1.HashMap的工作原理图 下图引用自:http://www.admin10000.com/document/3322.html 2.HashMap初始化的时候我们可以这样理解:一个数组,每一个位置存储的是一个链表,链表里面的每一个元素才是我们记录的元素 3.下面我们来看put的源码: public V put(K key, V value) { if (key == null) return putForNullKey(value); int

转载: HashMap的工作原理

摘要 HashMap在java项目中占有举足轻重的地位,所以了解HashMap的工作原理很有必要. 1.前言 在探讨HashMap源码之前,先说一下HashCode,为什么呢?因为HashMap有一个特性是Key是唯一值,如何确定key的唯 一性呢,这就用到了hash算法.在HashMap(jdk1.7)的put方法实现中首先利用了hash()生成key的hashCode,然后比较 key的hashCode是否已经存在集合,如果不存在,就插入到集合,如果已存在,则返回null. 1.1 hash

从头认识java-15.7 Map(4)-介绍HashMap的工作原理-hash碰撞(经常作为面试题)

这一章节我们来讨论一下hash碰撞. 1.什么是hash碰撞? 就是两个对象的key的hashcode是一样的,这个时候怎么get他的value呢? 答案是通过equals遍历table那个位置上面的Entry链表. 2.例子 正常的例子: package com.ray.ch14; import java.util.HashMap; public class Test { public static void main(String[] args) { HashMap<Person, Dog>

openSessionInView的使用原理及性能分析

看到好多项目中用到了openSessionInView,这样的做法无非是开发方便,可以在JSP页面中操作数据库层方面的业务.下边说下openSessionInView的用法及性能问题. 使用: 1.增加一个Filter,该Filter用来控制事务及数据库的连接管理,代码如下: SessionFactory sessionFactory = lookupSessionFactory(request); Session session = null; boolean participate = fa

【转】由浅入深探究mysql索引结构原理、性能分析与优化

摘要: 第一部分:基础知识 第二部分:MYISAM和INNODB索引结构 1.简单介绍B-tree B+ tree树 2.MyisAM索引结构 3.Annode索引结构 4.MyisAM索引与InnoDB索引相比较 第三部分:MYSQL优化 1.表数据类型选择 2.sql语句优化 (1)     最左前缀原则 (1.1)  能正确的利用索引 (1.2)  不能正确的利用索引 (1.3)  如果一个查询where子句中确实不需要password列,那就用“补洞”. (1.4)  like (2)

Java中的数据结构有哪些?HashMap的工作原理是什么?

Java中常用数据结构 常用的数据结构有哈希表,线性表,链表,java.util包中有三个重要的接口:List,Set,Map常用来实现基本的数据结构 HashMap的工作原理 HashMap基于hashing原理,我们通过put(key,value)和get(key)方法存储和获取对象元素,当我们将key值传递给put()方法时,会自动调用对象元素的hashcode方法计算hashcode,然后根据hashcode确定对象元素具体存储的位置: 获取对象时,我们根据键对象的equals方法找到具

Java8 中 ConcurrentHashMap工作原理的要点分析

简介: 本文主要介绍Java8中的并发容器ConcurrentHashMap的工作原理,和其它文章不同的是,本文重点分析了不同线程的各类并发操作如get,put,remove之间是如何同步的,以及这些操作和扩容操作之间同步可能出现的各种情况.由于源代码的分析肯定会有所纰漏,希望大家积极指出错误. 欢迎探讨,如有错误敬请指正 如需转载,请注明出处 http://www.cnblogs.com/nullzx/ 1.Java8中 ConcurrentHashMap的结构 图片来源(http://www

Java HashMap的工作原理(转载)

原文地址:http://www.importnew.com/10620.html 面试的时候经常会遇见诸如:"java中的HashMap是怎么工作的","HashMap的get和put内部的工作原理"这样的问题.本文将用一个简单的例子来解释下HashMap内部的工作原理.首先我们从一个例子开始,而不仅仅是从理论上,这样,有助于更好地理解,然后,我们来看下get和put到底是怎样工作的. 我们来看个非常简单的例子.有一个"国家"(Country)类