java map的底层_3.8Java高级编程【Map接口,HashMap的底层实现原理】

Map接口,HashMap的底层实现原理

1.map接口的实现类(存储的是双列数据,具有key-value的特点)

HashMap:作为Map的主要实现类,线程不安全,存储null的key与value

LinkedHashMap:遍历元素时,可以按照添加的顺序实现遍历,因为在添加元素的时候,添加了两个引用,前一个元素是什么,后一个元素是什么,适用于频繁的遍历操作

TreeMap:保证按照添加元素的key进行排序,实现排序遍历,考虑key的自然排序与自定义排序

HashTable:作为Map的古老实现类,线程安全,不能存储null的key与value

Properties:常用来处理配置文件,key-value都是String类型

2.Map结构的理解

Map中的key是无序的,不可重复的,使用Set存储所有的key ---》hashMap中key所在的类要重写hashcode和equals方法

Map中的value是无序的,可重复的,使用Collection来存储所有的value

一个键值对构成了一个Entry对象

Map中的Entry是无序的,不可重复的,使用Set存储所有的Entry

3.HashMap与HashTable的异同点

相同点:都是Map接口的实现类

不同点:HashMap是Map接口的主要实现类,线程不安全,效率高,可以存储key-value都为null的数据

HashTable是Map接口的古老实现类,线程安全,效率低,不可以存储key-value都为null的数据

4.HashMap的底层实现原理?以jdk7为例说明

HashMap  hashmap = new HashMap();

在实例化以后,底层创建了一个长度为16的一维数组Entry[] table

.....可能执行了很多次put操作....

map.put(key1,value1):

首先调用key1所在类的hashcode()计算key1的哈希值,此哈希值经过某种算法的计算后,得到在数组中的存放位置

如果此位置上的数据为空,key1-value1添加成功 ----------情况1

如果此位置上的数据不为空(意味着此位置上的一个或者多个数据以链表的形式存在),比较key1的哈希值是否与已经存在的一个或者多个数据的key的哈希值是否相同

如果key1的哈希值与已经存在数据的哈希值都不相同,此时key1-value1添加成功----------情况2

如果key1的哈希值与已经存在的某个数据(key2-value2)哈希值相同,继续比较equals()方法

如果equals返回false,则key1-value1添加成功 ----------情况3

如果equals返回true,则将key2替换为key1

注:情况2与情况3,此时的key1-value1和原来的数组以链表方式存储

在不断的添加过程中,会涉及到扩容问题,默认的扩容方式是扩大为原来的2倍,并将原有的数据复制到新的数组中

jdk8较于jdk7底层实现方面有些不同

1.new HashMap()的时候,底层没有创建一个长度为16的数组

2.底层的数组是Node[] 并非原来的Entry[]

3.首次指行put操作的时候,底层才会创建长度为16的Node[]数组

4.jdk7底层是以数组+链表  ,jdk8底层是以数组+链表+红黑树

当数组的某个索引位置上以链表存储数据的个数  > 8个并且数组的长度  > 64的时候,此时会以红黑树的形式存储,方便查找

5.HashMap源码中的一些常量

DEFAULT_INITIAL_CAPACITY: HashMap的默认容量 16

DEFAULT_LOAD_FACTOR:HashMap的默认加载因子 0.75

threshold:扩容的临界值 =  默认容量 *  默认加载因子 = 16 * 0.75 = 12

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值