分享

30个人面试Java程序员,就我会这个框架,所以HR选了我

 timtxu 2017-05-14

前面我们也讲了集合框架需要的一些概念和接口,现在在讲另一种接口类型

Map接口

Map,图,是一种存储键值对映射的容器类,在Map中键可以是任意类型的对象,但不能有重复的键,每个键都对应一个值,真正存储在图中的是键值构成的条目。下面是接口Map的类结构。

从上面这张图中我们可以看到接口Map提供了很多查询、更新和获取存储的键值对的方法,更新包括方法clear、put、putAll、remove等等,查询方法包括containsKey、containsValue等等。Map接口常用的有三个具体实现类,分别是HashMapLinkedHashMap、TreeMap。

  1. HashMap

HashMap是基于哈希表的Map接口的非同步实现,继承自AbstractMap,AbstractMap是部分实现Map接口的抽象类。在平时的开发中,HashMap的使用还是比较多的。我们知道ArrayList主要是用数组来存储元素的,LinkedList是用链表来存储的,那么HashMap的实现原理是什么呢?先看下面这张图:

HashMap原理.jpg

在之前的版本中,HashMap采用数组+链表实现,即使用链表处理冲突,同一hash值的链表都存储在一个链表里。但是当链表中的元素较多,即hash值相等的元素较多时,通过key值依次查找的效率较低。而JDK1.8中,HashMap采用数组+链表+红黑树实现,当链表长度超过阈值(8)时,将链表转换为红黑树,这样大大减少了查找时间。

下面主要通过源码介绍一下它的实现原理。(如果想要更多的企业求职加分项目,案例,可以来一下我的Java群632119504,每天都会精挑细选一个特效,项目出来详细讲解,分享!包括答疑解惑!)

HashMap存储元素的数组

transient Node table;

数组的元素类型是NodeNode继承自Map.Entry,表示键值对映射。

接下来我们看下HashMap的get操作。

HashMap的get操作。

到这里HashMap的大致实现原理应该很清楚了,有几个需要关注的重点是:HashMap存储元素的方式以及根据Hash值确定映射在数组中的位置还有JDK 1.8之后加入的红黑树的。

在HashMap中要找到某个元素,需要根据key的hash值来求得对应数组中的位置。对于任意给定的对象,只要它的hashCode返回值相同,那么程序调用hash(int h)方法所计算得到的hash码值总是相同的。我们首先想到的就是把hash值对数组长度取模运算,这样一来,元素的分布相对来说是比较均匀的。但是,“模”运算的消耗还是比较大的,在HashMap中,(n - 1) & hash 用于计算对象应该保存在table数组的哪个索引处。HashMap底层数组的长度总是2的n次方,当数组长度为2的n次幂的时候,(n - 1) & hash 算得的index相同的几率较小,数据在数组上分布就比较均匀,也就是说碰撞的几率小,相对的,查询的时候就不用遍历某个位置上的链表,这样查询效率也就较高了。

2.LinkedHashMap

LinkedHashMap继承自HashMap,它主要是用链表实现来扩展HashMap类,HashMap中条目是没有顺序的,但是在LinkedHashMap中元素既可以按照它们插入图的顺序排序,也可以按它们最后一次被访问的顺序排序。

3.TreeMap

TreeMap基于红黑树数据结构的实现,键值可以使用Comparable或Comparator接口来排序。TreeMap继承自AbstractMap,同时实现了接口NavigableMap,而接口NavigableMap则继承自SortedMapSortedMap是Map的子接口,使用它可以确保图中的条目是排好序的。

在实际使用中,如果更新图时不需要保持图中元素的顺序,就使用HashMap,如果需要保持图中元素的插入顺序或者访问顺序,就使用LinkedHashMap,如果需要使图按照键值排序,就使用TreeMap。

至于接口与接口之间实例对比,笔墨太长,我已上传至群文件,大家可以加群下载,后续内容请关注本头条号,每天定时更新哦。

上一页:Java集合框架(二)Collection接口

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多