`
BradyZhu
  • 浏览: 247738 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

HashMap的存储结构及原理

 
阅读更多

1、HashMap的数据结构(HashMap通过hashcode对其内容进行快速查找,是无序的)


数据结构中有数组和链表来实现对数据的存储,但这两者基本上是两个极端。

数组 :数组的存储区是连续的,占用内存严重,故空间复杂度很大。但数组的二分查找时间度小;数组的特点:寻址容易,插入和

删除困难。

链表 :链表的储存区离散,占用内存比较宽松,故空间复杂度很小,但时间复杂度大;链表的特点:寻址困难,插入和删除容易。


哈希表

HashMap是由数组+链表组成;寻址容易,插入和删除容易。(存储单元数组Entry[],数组里面包含链表

HashMap其实也是由一个线性的数组实现的。所以可以理解为其存储数据的容器就是一个线性容器;

HashMap里面有一个内部静态类Entry,其重要的属性有key,value,next,从属性key,value 就可以很明显的看出来 Entry就是

HashMap键值对实现的一个基础bean;也就是说HashMap的基础就是一个线性数组,这个数组就是Entry[],Map里面的内容都保存

在Entry[]中;

    /**
     * The table, resized as necessary. Length MUST Always be a power of two.
     */

    transient Entry[] table;

2、HashMap的存取实现


2.1:存储

这里HashMap用了一个算法。

//存储时候:

int hash=key.hashCode(); //获取key的hashCode,这个值是一个固定的int值

int index=hash%Entry[].length;//获取数组下标:key的hash值对Entry数组长度进行取余

Entry[index]=value;


注意:如果两个key通过hash%Entry[].length得到的index相同,会不会覆盖?

是不会的。Entry类有一个next属性,作用是指向下一个Entry。打个比方, 第一个键值对A进来,通过计算其key的hash得到的

index=0,记做:Entry[0] = A。一会后又进来一个键值对B,通过计算其index也等于0,现在怎么办?HashMap会这样做:B.next =

A,Entry[0] = B,如果又进来C,index也等于0,那么C.next = B,Entry[0] = C;这样我们发现index=0的地方其实存取了A,B,C三个键值对,他

们通过next这个属性链接在一起。所以疑问不用担心。

也就是说Entry[]数组中存储的是最后插入的数据


	 public V put(K key, V value) {
	        if (key == null)
	            return putForNullKey(value); //null总是放在数组的第一个链表中
	        int hash = hash(key.hashCode());
	        int i = indexFor(hash, table.length);
	        //遍历链表
	        for (Entry<K,V> e = table[i]; e != null; e = e.next) {
	            Object k;
	            //如果key在链表中已存在,则替换为新value
	            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
	                V oldValue = e.value;
	                e.value = value;
	                e.recordAccess(this);
	                return oldValue;
	            }
	        }
	        modCount++;
	        addEntry(hash, key, value, i);
	        return null;
	    }

	 
	void addEntry(int hash, K key, V value, int bucketIndex) {
	    Entry<K,V> e = table[bucketIndex];
	    table[bucketIndex] = new Entry<K,V>(hash, key, value, e); //参数e, 是Entry.next
	    //如果size超过threshold,则扩充table大小。再散列
	    if (size++ >= threshold)
	            resize(2 * table.length);
	}


2.2:取值

获取key的hashcode指,通过hash值去hash%Entry[].length 获取Entry[hash%Entry[].length],定位到该数组元素之后,再遍历该元

素处的链表。

//取值时候:

int hash=key.hashCode();

int index =hash%Entry[].length;

return Entry[index];


     public V get(Object key) {
	        if (key == null)
	            return getForNullKey();
	        int hash = hash(key.hashCode());
	        //先定位到数组元素,再遍历该元素处的链表
	        for (Entry<K,V> e = table[indexFor(hash, table.length)];
	             e != null;
	             e = e.next) {
	            Object k;
	            if (e.hash == hash && ((k = e.key) == key || key.equals(k)))
	                return e.value;
	        }
	        return null;
	}


当哈希表的容量超过默认容量时,必须要调整table的大小。当容量达到最大值时,该方法Integer.MAX_VALUE返回,这时,就需要创建

一张表,将原来的表映射到新表中。


3、HashMap、HashTable和ConcurrentHashMap的线程安全问题

HashMap:线程不安全的。
HashTable:锁住整张hash表,让线程独占。hashMap允许为空。通过分析Hashtable就知道,synchronized是针对整张Hash表的,
每次锁住整张表

让线程独占,安全的背后是巨大的浪费。

ConcurrentHashMap:一个更快的hashmap,它提供了好得多的并发性。多个读操作几乎总可以并发地执行。他是锁段(默认:把hash表分为16个

,在get,put,remove等操作中,ConcurrentHashMap只锁定当前需要用到的段,只有在求size的时候才锁定整张hash表。

分享到:
评论

相关推荐

    HashMap原理.docx

    HashMap是一个散列桶(数组和链表),它存储的内容是键值对(key-value)映射HashMap采用了数组和链表的数据结构,能在查询和修改方便继承了数组的线性查找和链表的寻址修改HashMap是非synchronized,所以HashMap很快...

    HashMap底层实现原理HashMap与HashTable区别HashMap与HashSet区别.docx

    HashMap、HashTable和HashSet是Java中常用的数据结构,它们的底层实现原理以及区别如下:HashMap底层实现原理: HashMap基于哈希表(HashTable)实现,它通过散列算法将键值对映射到数组中。在HashMap中,每个键值对...

    HashMap原理分析及性能优化

    HashMap是一个用于存储Key-Value键值对的集合,每一个键值对也叫做Entry。这些个键值对(Entry)分散存储在一个数组当中,这个数组就是HashMap的主干。 数据结构(JDK1.8):Node[] table; 数组+链表+红黑树

    Java的HashMap的工作原理是什么

    hashmap是一个key-value键值对的数据结构,从结构上来讲在jdk1.8之前是用数组加链表的方式实现,jdk1.8加了红黑树,hashmap数组的默认初始长度是16,hashmap数组只允许一个key为null,允许多个value为null hashmap的...

    java中HashMap的原理分析

    HashMap在Java开发中有着非常重要的角色地位,每一个Java程序员都应该了解HashMap。详细地阐述HashMap中的几个概念,并深入探讨HashMap的内部结构和实现细节,讨论HashMap的性能问题

    HashMap(二)原理讲解

    1.HashMap的继承体系是...3.底层存储结构介绍? 4.put数据原理分析? Node数组的长度一定是 2^n次方长度 5.什么是Hash碰撞?链化? 指的是,相同 hash 值的键值对会发生冲突组成链表 时间复杂度 由O(1)退化为O(n) 6.J

    HashMap 源码分析

    首先,我们了解一下HashMap的底层结构历史,在JDK1.8之前采用的是数组+链表的数据结构来存储数据,是不是觉得很熟悉,没错这玩意在1.8之前的结构就和HashTable一样都是采用数组+链表,同样也是通过链地址法(这里简称...

    关于hashMap的一些讨论

    HashMap的实现原理的一些讨论,包括数据结构实现,存储数据的实现以及性能参数和Fail-Fas机制。

    JavaSE基础面试题.docx

    17.HashMap、Hashtable、ConcurrentHashMap底层实现原理及区别 18.HashMap底层数据结构 19.说说HashMap如何处理碰撞的,或者说说它的扩容? 20.jdk7/8中对HashMap做了哪些改变? 21.负载因子为什么会影响HashMap性能...

    java7hashmap源码-JAVA-:JAVA-

    定义的这个数据结构中,如果每次都hashMap.put(string, new hashtable&lt;&gt;)的话会覆盖掉之前的hashtable,所以最好先定义hashtable,存储完成后再放入map中,或者hashtable先get 出value再put进入新value。 5 new ...

    equals 和 hashCode两者效果分析详解.docx

    但是为什么JavaDoc明确的告诉我们, hashCode()...HashMap底层用于存储数据的结构其实是散列表(也叫哈希表),散列表是通过哈希函数将元素映射到数组指定下标位置, 在Java中,这个哈希函数其实就是hashCode()方法。

    java面试八股文总结.pdf

    答案:HashMap是Java中的一个哈希表实现的数据结构,用于存储键值对。它通过键的哈希码来快速定位值的位置。当我们将键值对放入HashMap时,首先计算键的哈希码,然后根据哈希码找到对应的桶(存储位置),如果桶中...

    java高级工程师、技术专家、架构师、项目经理面试宝典.rar

    类装载器(ClassLoader)(用来装载.class文件) 执行引擎(执行字节码,或者执行本地方法) 运行时数据区(方法区、堆、java栈、PC寄存器...3.Map或者HashMap的存储原理 答:HashMap是由数组+链表的一个结构组成。

    Java和Android的LRU缓存及实现原理

    一、概述 Android提供了LRUCache类,可以方便的使用它来实现LRU算法的缓存。Java提供了LinkedHashMap,可以用该类很方便的实现LRU算法,Java的...首先需要说明的是,HashMap将每一个节点信息存储在Entry结构中。Entry

    ConcurrentHashMap的实现原理(JDK1.7和JDK1.8).pdf

    哈希表就是一种以 键-值(key-indexed) 存储数据的结构,我们只要输入待查 找的值即 key,即可查找到其对应的值。 哈希的思路很简单,如果所有的键都是整数,那么就可以使用一个简单的无序数 组来实现:将键作为索引...

    TheirNotes::ledger: 《互联网后端知识大全》「前人栽树, 后人乘凉; 它山之石, 可以攻玉」java

    Zookeeperzab 原理解析TomcatNetty内存管理底层原理Sentinel底层原理Linux计算机网络HTTPSOCKETTCPNIO通信协议解决方案负载均衡SSO点赞评论计数设计订单接口幂等性编程素养设计模式常用调试指令网络相关工具包数据...

    【Java基础】集合框架-面试题.pdf

    【Java基础】集合框架-面试题。包含: 1. ArrayList 和 Vector 的区别; 2、ArrayList,Vector, LinkedList 的存储性能和特性;...4. HashMap 的数据结构、工作原理 等Java集合部分经常遇到的面试题总结

    涵盖了90%以上的面试题

    hashmap的底层原理 hashmap产生死锁的原因 hashmap的容量为什么一定要是2的幂呢 TreeMap的底层原理 HashMap,Hashtable和ConcurrentHashMap的区别 在ArrayList和LinkedList尾部添加元素,谁的效率更高 如果HashMap或者...

    java面试题,180多页,绝对良心制作,欢迎点评,涵盖各种知识点,排版优美,阅读舒心

    【Redis】Redis的存储结构,或者说如何工作的,与mysql的区别?有哪些数据类型? 133 【Redis】项目中用到redis,为什么选用redis 133 独特的键值对模型 134 内存储存,速度极快 135 丰富的附加功能 136 完善的文档 ...

    最新Java面试题视频网盘,Java面试题84集、java面试专属及面试必问课程

    面试题包含了不同技术层面的面试问题,同时也能对一些没有面试开发经验的小白给予不可估量的包装, 让你的薪水绝对翻倍, 本人亲试有效.Java面试题84集、java面试专属及面试必问课程,所有的面试题有视屏讲解, 解答方案....

Global site tag (gtag.js) - Google Analytics