Java HashMap源码深入分析讲解
1.HashMap是数组+链表(红黑树)的数据结构。
数组用来存放HashMap的Key,链表、红黑树用来存放HashMap的value。
2.HashMap大小的确定:
1) HashMap的初始大小是16,在下面的源码分析中会看到。
2)如果创建时给定大小,HashMap会通过计算得到1、2、4、8、16、32、64....这样的二进制位作为HashMap数组的大小。
3.如何将key映射成数组角标:
我们都知道数组的下标是0,1,2,3,4,5,6.....这样的连续整数,那么、HashMap是怎么将Key转换成对应的数组角标的呢?
4.Value值如何存储?
HashMap将key的hashCode转换为数组角标,必然会存在多个元素的key转换成同一个角标的情况。针对这样的情况,HashMap采用链表和红黑数的方式存储Value值。java8以后默认先以单链表的方式存储。当单链表中的元素超过8个后,单链表会转换成红黑树数据结构。当红黑树上的节点数量少于6个会重新变为单链表结构。
5.put实现原理:
1)通过算法,计算出key对应的数组角标。
2)取出数组角标存储的节点,如果为null直接存储,如果不为null,则对链表进行遍历,先比较两个元素的hash值,再判断key的equale,如果一样,说明key已经存在,则不存储,这也就是hashmapKey不能重复的原因。如果不一样,则以链表或红黑树的方式存储。
6.get方法,HashMap如何取出元素。
取数据时,如何判断传入的key和map中的key是同一个key呢?
e.hash == hash &&
((k = e.key) == key || (key != null && key.equals(k)))
通过源码可以看到,必须满足两个条件,hash值必须相等,然后再判断,key的引用是否一致,或者key的equals是否是true。这也就是为啥要同时复写对象的hashCode和equals方法的原因。
7.HashMap的扩容
扩容因子: static final float DEFAULT_LOAD_FACTOR = 0.75f;
默认大小:static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
扩容阈值:int threshold;
到此这篇关于Java HashMap源码深入分析讲解的文章就介绍到这了,更多相关Java HashMap内容请搜索编程学习网以前的文章希望大家以后多多支持编程学习网!