前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ArrayList.add源码

ArrayList.add源码

原创
作者头像
用户6105233
修改2019-08-26 11:09:40
5800
修改2019-08-26 11:09:40
举报
文章被收录于专栏:沉淀沉淀

最近在写代码的时候,发现在定义一个空的列表时,使用list.add方法向列表中添加一个元素,会抛出空指针的异常。(0.0虽然这是一个很常见的低级错误,代码大意如下

List list=null;

list.add(1);

原因是不能对空列表进行操作。但是由此就想到为什么new一个ArrayList的时候,调用ArrayList.add方法向ArrayList中添加一个元素的时候不会报空指针的异常呢?ArrayList是如何处理的呢?当然了,解决问题最直观的方法就是阅读源码。因此,借此机会也阅读了一下ArrayList.add的相关源码。

在ArrayList的构造方法中中,ArrayList无参构造方法默认是一个空数组,但注释说是容量为10的数组。其实ArrayList的容量是在调用add方法时初始化的。add方法是List接口中声明的通用方法。ArrayList的add源码如下所示:

size是当前集合拥有的元素个数(不是容量大小,且未算进准备新增的元素)。在add方法中调用了ensureCapacityInternal对ArrayList进行扩容,size+1是保证新进入的元素能满足要求。接下来看ensureCapacityInternal方法:

  • 第1行判断elementData是否是一个空数组(初始化容量为0,或者调用无参构造函数),如果是,则执行第#2行
  • 第2行选取minCapacity和DEFAULT_CAPACITY之间一个比较大的值。其中DEFAULT_CAPACITY是一个静态的值为10的常量
  • 第3行执行ensureExplicitCapacity方法,该方法源码如下:

  • 如果传进来的容量大于elementData的容量(这里是容量,不是element里面元素的个数),则执行下一句。
  • 调用grow方法,grow方法源码如下所示:

第#1行,将扩容前elementData数组容量赋值给oldCapacity 第#2行,将oldCapacity左移一位,然后再加上oldCapacity,最后赋值给newCapacity。就是将oldCapacity扩容1.5倍赋值给newCapacity。 第#3行,如果扩充后的容量newCapacity比传进来的参数minCapacity还小,则直接使用minCapacity。这种情况发生在ArrayList容量为空的情况,即oldCapacity=0,minCapacity=1时。 第#5行如果扩容后新的容量大于MAX_ARRAY_SIZE,则调用hugeCapacity方法给newCapacity赋值。MAX_ARRAY_SIZE初始化如下:

hugeCapacity源码如下:

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

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

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