那些注意不到的细节之ArrayList

ArrayList

ArrayList,在写程序的时候经常用到,觉得也就那样,会往里面插数据或者获取数据即可,但是在看完书本对他有了进一步的认识.ArrayList在书中也称之为数组列表,看源码可以知道,他内部数据存储是使用的Object数组.并且一开始默认是用的空数组来初始化的.

elementData是列表的数据,size是列表实际元素的大小. 

注意的地方

ArrayList的容量与数组的大小有一个非常重要的区别。 如果为数组分配 100 个元素的存储空间,数组就有 100 个空位置可以使用。比如数组下面的操作是可以的,正常的.

但是对于ArrayList,这样就有问题了

报错:

看看源码来解开我们的疑惑

初始化的时候,调用它的指定容量的构造函数,我们可以看到,这个时候,确实,根据我们的初始化大小,new了一个Object数组.那奇怪了,不应该我们没法set进去的啊

继续看一下set源码,可以看到,set之前,要进行一个范围检查.看看是否超过范围了

再进去查看rangecheck的源码,是的,这下明白了,是根据我们要插入的位置和当前列表的size进行比较来确定的.所以为什么抛出了IndexOutOfBoundsException就可以理解了.

上面初始化大小的源码里,确实,只是开辟了100个大小的数组,但是他并没有更新size,size这个时候依然是空的也就是0.所以我们进行set操作的时候,在进行范围检查的时候,就抛出这个异常了.

所以书上也是不建议我们用set方法来添加新元素,毕竟本身这个方法的目的就不是用来添加元素的.只是用来改变已有内容的

 

其他的方法同样的,比如get方法,他一样做范围检查.当然说到这里还要小心一个方法就是add(index,element)了,他同样也会先进行范围检查.他的源码如下:

不同的是,他调用的是rangeCheckForAdd方法,和上面的set不是同一个检查方法,看一下这个方法会有什么不同.

可以看到,这个方法是允许边界值的,不像set方法是index>=size.所以在初期的时候,我们这样操作是不会报错的.

但是如果你这样写,那就会报错.

总结:

所以列表初始化的容量大小,确实内部已经开辟了指定容量大小的数组空间,但是由于各种操作都会进行rangeCheck,所以数组列表里面没有元素的时候,不建议进行get,set,remove等操作,add操作是安全的.顺便说一下,看上面的源码可以看到对增删改的操作都是没有做线程安全的约束的,所以ArrayList在多线程环境下面是不安全的.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值