前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >从源码分析ArrayList和Vector的区别

从源码分析ArrayList和Vector的区别

作者头像
大猫的Java笔记
发布2020-09-30 01:35:26
3910
发布2020-09-30 01:35:26
举报
文章被收录于专栏:大猫的Java笔记

1.Vector和ArrayList

可能你对ArrayList平时耳熟能详,但是你可能却不知道Vector,Vector其实和ArrayList的用法基本一致,不同的在于Vector是线程安全的而ArrayList非线程安全。Vector之所以线程安全是因为在实现的方法上加了synchronized修饰符。

ArrayList和Vector的类继承和实现图如下

2.ArrayList和Vector的add方法对比

Vector的add方法实现如下,在看Vector方法前我们先看一下他的构造方法,当我们默认调用第一个构造方法时实际上会指定一个初始化的数组容量为10,然后指定容量增量为0。

ArrayList的add方法实现如下,在看ArrayList方法前我们同样先看一下他的构造方法,与Vector不同,ArrayList并不会在构造时就分配数组的空间容量;而是将默认的静态数组DEFAULTCAPACITY_EMPTY_ELEMENTDATA赋值给elementData。当然如果你指定容量的话实现方式就是根据容量的大小来决定是否初始化数组。

调用指定容量的构造方法。

Vector的add方法实现,首先Vector的add方法是加了synchronized即每次只能有一个线程进行访问,然后将modCount自增,调用ensureCapacityHelper方法,ensureCapacityHelper实际上就是检查数组的容量已经满了,如果满了那么执行grow方法对数组进行扩容。

ensureCapacityHelper方法检查数组是否需要扩容。

grow方法对数组进行扩容,我们可以看到扩容的机制是先判断容量增量capacityIncrement是否为0,不为0则扩容的大小则是原数组容量加上capacityIncrement的值,如果为0则按照原数组容量的2倍进行扩容。最后回到add方法将值放入到elementData数组中并返回true。

ArrayList的add方法实现,首先拿到size+1的值调用ensureCapacityInternal进行容量的初始化。前面我们说过ArrayList并不会在构造函数中就对数组容量初始化。

ensureCapacityInternal方法中先判断elementData是否等于DEFAULTCAPACITY_EMPTY_ELEMENTDATA,DEFAULTCAPACITY_EMPTY_ELEMENTDATA在无参构造方法中已经给了elementData(前面说过),那么如果第一次进入肯定是相等的。此时会拿到容量然后调用ensureExplicitCapacity方法最后调用grow方法对容量进行初始化。

与Vector的grow方法不同,ArrayList的扩容机制是1.5倍进行扩容。

最后我们总结一下ArrayList的add方法和Vector的add方法区别如下

1.ArrayList的add方法非线程安全,Vector的add方法线程安全。

2.ArrayList采用1.5倍扩容,而Vector则根据是否设置了扩容增量,如果设置了则在原容量上加上扩容增量进行扩容,没有设置则直接2倍扩容。

3.Vector在构造方法中就直接初始化数组且指定容量,而ArrayList在add方法中才进行初始化数组。

其余的的方法大致实现的方式都是类似的,主要区别就在于上面这三点上。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-09-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 大猫的Java笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档