深入ArrayList,Vector底层,了解2者的区别

想必大家除了String类,那么ArrayList类,用的也不少吧,那么今天我们去底层看看这个类的面目
作者博客:书生个人博客
##一.了解ArrayList类,那么我们先从构造函数开始说:

这里写图片描述

从上图我们可以知道

如果你是

ArrayList<String> b=new ArrayList<>();

那么会调用无参的构造函数,而无参的会调用有参的,并给的大小是10,那么出现了个问题,我们平常用的话,感觉ArrayList是没有大小的啊,可以一直add,不像我们普通的数组那样,是固定大小的啊。
对啊,那如果平常你的数组不够用,再添加的话,会出现数组下标越界异常,那么这时我们是不是可以在创建一个新的数组(比之前的大),然后复制过来(arrayCopy()函数,下面有说)。那么ArrayList底层是不是默默的帮我们做了呢 接着看
这里写图片描述

我们接着看

 ensureCapacityInternal(size + 1);

size:是一个成员变量,初始化为0
这里写图片描述

这里写图片描述

从上面我们可以看到,当minCapacity>数组的大小时,会执行grow()函数,而这个函数就是扩容数组用的

(什么是minCapacity??

这里写图片描述

minCapacity与size有关,很简单,一开始size为0,然后把进来的e放在数组中,再size+1,每次add,我们先要执行 ensureCapacityInternal(size + 1);,主要是判断数组是否满了,然后对其进行扩容,那他是怎么扩容的呢,是不是也是用数组复制方法呢?接着看

grow函数

这里写图片描述

这儿有一段代码:int newCapacity = oldCapacity + (oldCapacity >> 1),>>是移位运算符,相当于int newCapacity = oldCapacity + (oldCapacity/2),但性能会好一些。,也就是新的数组是原来数组的1.5倍,并给原来的数组,这样,那数组是不是无形的变大1.5倍了啊.

我们再看一下复制函数的代码:

这里写图片描述

它还调用了一个

这里写图片描述
接着我们再看arraycopy()方法
好奇怪,这个方法只有定义,却没有实现,方法用了一个native来修饰。native的方法,是由其它语言来实现的,一般是(C或C++),所以这儿没有实现代码。这是一个数组拷贝方法,大家还在写for循环拷贝数组吗?以后多用这个方法吧,简单又方便还能获得得更好的性能。

我们接着看一下size()的源码:

这里写图片描述

一开始,size为0,而数组大小就10,所以我们这直接返回时size,代表的时这个数组目前有多少个元素,而不是数组的大小

##二.Vector与ArrayList的区别呢?
Vector源码跟ArrayList差不多,就是
这里写图片描述

这里写图片描述

1.Vector 只要是关键性的操作,方法前面都加了synchronized关键字,来保证线程的安全性。当执行synchronized修饰的方法前,系统会对该方法加一把锁,方法执行完成后释放锁,加锁和释放锁的这个过程,在系统中是有开销的,因此,在单线程的环境中,Vector效率要差很多。(多线程环境不允许用ArrayList,需要做处理)。

###2.至于底层数组的扩容区别,
这里写图片描述

和ArrayList和Vector一样,同样的类似关系的类还有HashMap和HashTable,StringBuilder和StringBuffer,后者是前者线程安全版本的实现。希望以后大家在面试过程中,能说出个因为所以,而不是一味的去背面试题,唯有理解,无需再背。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值