Java ArrayList的扩容机制 以及与LinkedList性能对比

目录

一、ArrayList的扩容机制

1、ArrayList创建时的长度

二、ArrayList和LinkedList对比

1、ArrayList的特性

2、LinkedList的特性

3、初步比较

三、fail-fast与fail-safe


一、ArrayList的扩容机制

1、ArrayList创建时的长度

(1)ArrayList()会是长度为0的数组

(2)ArrayList(int initialCapacity)会是指定容量的数组

(3)ArrayList(Collection<?extends E> c)会是以c的大小作为数组的大小

(4)add(Object o)首次扩容为10,再次扩容为之前容量的1.5倍

解释:

ArrayList按无参构造创建时大小为0,当第一次调用add方法时会扩容到10,我们继续调用add方法直至10个空位被添满,再次调用add方法时,有于没有空位了,此时开始扩容,将数组大小扩容到之前大小的1.5倍,即之前大小是10则扩容后大小为15,再次扩容为15*1.5,以此类推。

(5)addAll(Collection c)没有元素时,扩容为Math.max(10,实际元素个数),有元素时为Math.max(原容量的1.5倍,实际元素个数)

解释:

与add方法扩容方法类似,但又有一定区别,主要区别是,当调用addAll方法插入的大小大于空位大小时进行扩容,如果需要扩容的大小大于了原规则扩容的大小,则会以该扩容大小进行扩容:

简单的案例:

刚开始数组长度为0,调用addAll方法插入一个容量为11的集合,原本应该按照10来扩容的,但由于11>10,所以此时直接扩容到11,再次调用add方法插入一个容量为11*1.5+1的集合,此时又超过了原规则扩容的大小,又以11*1.5+1大小进行扩容。

简单来说,就是按照扩容规则中较大的那一个进行扩容,即Math.max(规则计算扩容大小,实际插入数据大小)

二、ArrayList和LinkedList对比

1、ArrayList的特性

(1)基于数组,需要连续内存

(2)随机访问快(根据下标访问)

(3)尾部插入、删除性能可以,其他部分插入、删除都会移动数据,因此性能会低

(4)优点:可以利用cpu缓存,局部性原理

2、LinkedList的特性

(1)基于双向链表,无需连续缓存

(2)随机访问慢(要沿着链表遍历)

(3)优点:头尾插入、删除性能高

(4)占用内存多

3、初步比较

ArrayList综合性能较高,建议多使用,适合情形:不须要频繁插入和删除数据到数组头部和前面部分,查询效率比LinkedList高。

LinkedList对于某些特定情况效率高,一般仅适合这些场景:需要频繁的插入、删除数组头部元素和前面部分时。对于中间部分的元素,由于其插入、删除前需要先遍历到该点,所以该情况下效率低于ArrayList,不推荐。

三、fail-fast与fail-safe

ArrayList是fail-fast的典型代表,遍历的同时不能修改,尽快失败。

CopyOnWriteArrayList是fail-safe的典型代表,遍历的同时可以修改,原理是读写分离。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值