集合源码分析

 

ArrayList集合源码分析

jdk7版本:底层会初始化数组,数组的长度为10。当要添加第11个元素的时候,底层的elementData数组已满,则需要扩容。默认扩容为原来长度的1.5倍。并将原有数组中的元素复制到新的数组中。

jdk8:先创建一个没有元素的数组,当添加第一个元素的时候开始初始化一个长度为10 的数组,然后把元素放入数组。后面的操作跟jdk7一样。

小结:

jdk1.7.0_07版本中:ArrayList类似于饿汉式

jdk1.8.0_271版本中:ArrayList类似于懒汉式

Vector源码分析

jdk8版本(相较jdk7没有变化):底层初始化数组,长度为10。当添加第11个元素时,需要扩容。默认扩容为原来的2倍。

LinkedList

底层首先创建一个链表,每次创建一个节点就连接在上一个节点的后面。

Vector基本不使用了

ArrayList底层使用数组结构,查找和添加(尾部添加)效率高,时间复杂度O(1),删除和插入效率低,时间复杂度O(n)。

LinkedList底层使用双向链表结构,删除和插入操作效率高,时间复杂度(1),查找和添加(尾部添加)操作效率低,时间复杂度O(n)(有可能添加操作是O(1))

在选择了ArrayList的前提下,推荐使用:new ArrayList(int capacity):底层创建指定的capacity长度的数组,这样就避免了底层的扩容和数组的复制。

HashMap源码分析

创建对象的过程中,底层会初始化数组Emtry[] table = new Entry[16];

一个Map的键值对封装到一个Entry对象中,考虑将此对象添加到table数组中。

添加/修改的过程:

将键值对(Key1,value1)添加到当前的Map中:

首先,需要调用Key1所在类的hashCode()方法,计算Key1对应的哈希值1,此哈希值1经过某种算法(Hash() )之后,得到哈希值2。  哈希值2再经过某种算法(indexFor() ) 之后,就确定了键值对在数组table中的位置 i;

1.1如果此索引位置i的数组上没有元素,则(Key1,value1)添加成功   ----> 情况1

1.2如果此索引位置i 的数组上有元素(Key2,value2),则需要继续比较key1和key2的哈希值2 -->哈希冲突

        2.1 如果key1的哈希值2与key2的哈希值2不相同,则添加成功 ---> 情况2

        2.2如果key1的哈希值与key2的哈希值相同,则需要继续比较key1和key2的equals()。 要调用key1所在类的equals(),将key2作为参数传递进去。

                3.1调用equals(),返回false:则添加成功

                3.2 调用equals(),返回true:则认为key1和key2是相同的。默认情况下,value替换原有的value2.

说明:

情况1:将(key1,value1)存放到数组的索引i位置

情况2,情况3:(key1,value1)元素与现有的(key2,value2)构成单向链表结构,(key1,value1)指向(key2,value2)

随着不断的添加元素,在满足如下条件的情况下,会考虑扩容:

(size >= threshold) && (null  != table[i])

当元素个数达到临界值(数组的长度 * 加载因子)时,就考虑扩容。默认的临界值 = 16 * 0.75 (加载因子)

默认扩容为原来的2倍。

jdk8与jdk7的不同之处:

① 在jdk8中,当创建了HashMap实例之后,底层并没有初始化table数组。当首次添加(key,value)时,进行判断,如果发现table尚未初始化,则对数组进行初始化。

② 在jdk8中,HashMap底层定义了Node内部类,替换jdk7中的Entry内部类。意味着,我们创建的时Node[] 数组。

③ 在jdk8中,当前的(key,value)经过一系列判断之后,可以添加到当前的数组角标i中。如果角标中有元素,jdk7采用的是头插法,jdk8中采用的是尾插法。

④ jdk7:数组+ 单向链表;           jdk8 : 数组 + 单向链表 + 红黑树

什么时候会使用单项链表变为红黑树: 如果索引 i 位置上的元素个数达到8,并且数组的长度达到64时,我们就将索引 i 位置上的多个元素改为红黑树的结构进行存储。 修改的目的:降低了时间复杂度(时间复杂度变为了O(logn)),性能更高。

什么时候会使用红黑树变为单向链表: 当使用红黑树的索引 i 位置上的元素的个数低于6的时候,就会将红黑树结构退化为单向链表。

LinkedHashMap

1.LinkedHashMap与HashMap的关系:

LinkedHashMap是HashMap的子类。

LinkedHashMap在HashMap使用的数组+ 单向链表 + 红黑树的基础上,又增加了一对双向链表,记录添加的(key,value)的先后顺序。便于我们遍历所有的key-value。

HashSet和LinkedHashSet的源码分析

HashSet底层使用的是HashMap

LinkedHashSet底层使用的是LinkedHashMap

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值