ArrayList是Java开发中经常用到的集合类,它是List接口的实现类,具有很高的查询性能,但不是线程安全的。本文主要讲述了ArrayList的add(E e)方法及该方法中涉及到的容量扩容技术。

  • 本文大纲

1.ArrayList底层数据结构

2.add(E e)方法流程概览

3.add(E e)方法与扩容源码分析

说明:本文对ArrayList的源码分析是基于JDK8。

  • 正文

1.ArrayList底层数据结构

ArrayList的底层数据结构为一个Object数组,对应到源码中是:

transient Object[] elementData; // non-private to simplify nested class access

2.add(E e)方法流程概览

add(E e)方法的大致流程:

3.add(E e)方法与扩容源码分析

接着再看一下源码:

public boolean add(E e) {// 确保数组有足够的空间来存储对象eensureCapacityInternal(size + 1); // Increments modCount!!// 将对象e存放到数组的末尾elementData[size++] = e;return true;
}

ensureCapacityInternal方法主要是确保elementData数组有足够的空间来存储待添加的元素:
// 参数minCapacity是add(E e)方法中调用ensureCapacityInternal方法时传入的size + 1的值
private void ensureCapacityInternal(int minCapacity) {if (elementData == EMPTY_ELEMENTDATA) {minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);}ensureExplicitCapacity(minCapacity);
}

参数minCapacity是为了存放这个元素elementData数组所需要的最小的大小。比如,现在一个数组中存放了10个元素,再次向该数组存放一个元素时,那么这个minCapacity的值就是size + 1,即10 + 1 = 11。

private void ensureExplicitCapacity(int minCapacity) {modCount++;// overflow-conscious codeif (minCapacity - elementData.length > 0)
     // 存放新元素所需的最小容量大于elementData数组的长度
        grow(minCapacity);
}

如果存放新元素所需的最小容量大于elementData数组的长度,即当前数组的容量不足,不能再存放新的元素,那么将基于elementData数组进行扩容。

private void grow(int minCapacity) {// overflow-conscious codeint oldCapacity = elementData.length;int newCapacity = oldCapacity + (oldCapacity >> 1); // 计算新数组的容量,新数组的容量为原数组容量的1.5倍数。>>是移位运算符,oldCapacity >> 1表示oldCapacity除以2if (newCapacity - minCapacity < 0) // 针对当创建的ArrayList的容量大小为1时能够进行扩容(下面将详细分析)newCapacity = minCapacity;if (newCapacity - MAX_ARRAY_SIZE > 0)newCapacity = hugeCapacity(minCapacity);// minCapacity is usually close to size, so this is a win:elementData = Arrays.copyOf(elementData, newCapacity); // 进行数组拷贝,并将新产生的数组赋值给elementData
}

当我们在new ArrayList的时候,如果指定ArrayList的容量大小为1(比如,new ArrayList<>(1)),再进行add(E e)操作,在执行代码int newCapacity = oldCapacity + (oldCapacity >> 1)时,newCapacity的值为1,newCapacity与oldCapacity的值都为1,这样其实并没有进行扩容。if (newCapacity - minCapacity < 0)就是为避免这种情况,当newCapacity(此例中为1)的值小于minCapacity(此例中为2)时,就把minCapacity的值赋给newCapacity。

转载于:https://www.cnblogs.com/pedlar/p/10165630.html

ArrayList的add(E e)方法与扩容相关推荐

  1. arraylist/vector add()方法诡异之---多次add进去的对象最终都变成最后一次add进去的对象值...

    最近在写java程序时遇到了一个诡异的问题:一个vector或arraylist 对象,我在循环中依次使用add方法向容器中添加多个对象,最后输出容器中的内容发现容器中的对象值全都相同都变成最后一次a ...

  2. Java ArrayList add()方法与示例

    ArrayList类的add()方法 (ArrayList Class add() method) Syntax: 句法: public boolean add(T ele); public void ...

  3. ArrayList的几种初始化方法

    1.使用Arrays.asList方法 ArrayList<Object> obj = new ArrayList<Object>(Arrays.asList(Object o ...

  4. java 遍历方法_Java ArrayList遍历的3种方法

    首页 > 基础教程 > 集合框架 > ArrayList类 Java ArrayList遍历的3种方法 1. Iterator方法遍历 for(Iterator it2 = list ...

  5. java学习笔记20(Arraylist复习,Collection接口方法,迭代器,增强型for循环)

    集合:集合是Java提供的一种容器,可以用来存储多个数据: 集合与数组的区别:集合的长度是可变的,数组的长度是固定的 集合中存储的数据必须是引用类型数据: ArrayList回顾: public cl ...

  6. ArrayList的三种遍历方法

    ArrayList的三种遍历方法 import java.util.*; public class Test{ public static void main(String[] args) { Lis ...

  7. Java之List系列--ArrayList保证线程安全的方法

    原文网址:Java之List系列--ArrayList保证线程安全的方法_IT利刃出鞘的博客-CSDN博客 简介 本文介绍Java中的ArrayList.LinkedList如何进行线程安全的操作.为 ...

  8. java的arraylist_Java ArrayList排序的3种方法

    首页 > 基础教程 > 集合框架 > ArrayList类 Java ArrayList排序的3种方法 1. 使用Collections.sort()方法进行排序 ArrayList ...

  9. java arraylist 删除_Java ArrayList删除特定元素的方法

    来源 http://developer.51cto.com/art/201503/469612.htm ArrayList是最常用的一种java集合,在开发中我们常常需要从ArrayList中删除特定 ...

最新文章

  1. HP存储raid5两块硬盘离线lvm下vxfs文件系统恢复数据过程
  2. JVM性能调优实践:G1 垃圾收集器介绍篇
  3. python gui编程 从入门到项目实战_python GUI编程 QT5开发项目实战
  4. 计算机图形学试题a卷,计算机图形学复习题及答案
  5. 基于tutk方案的p2p源码_基于JAVA的局域网文件共享平台P2P实训项目源码(毕业设计 课程设计)...
  6. ORDER BY分类
  7. Web前端/辅助工具
  8. 经典java算法大全
  9. 如何使用Ubuntu安装QQ音乐Linux版本
  10. 美国交通安全管理局出台更加严格机场安全检查新规
  11. Python学习week3
  12. java中类成员的限定词_JAVA中类成员的限定词有以下几种、private ,public ,
  13. 从零开始开发一个大型网站
  14. 电脑为何连不上手机开的热点
  15. 散论陈寅恪先生《对科学院的答复》
  16. AI训练营金融风控学习笔记
  17. Android Studio使用真机(连接安卓手机驱动)调试教程
  18. 深入浅出 Babel 下篇:既生 Plugin 何生 Macros
  19. Linux下脚本对拍
  20. 三年级竖式计算机应用题,小学三年级数学上册脱式计算、竖式计算、应用题

热门文章

  1. 实时计算 Flink 版应用场景解读
  2. Flink 1.11.0 发布,有哪些值得关注的新特性?
  3. 认识 lib 目录里的 .so 文件
  4. 在sqlplus中操作blob和clob
  5. RMAN备份filesperset用法
  6. python中硬要写抽象类和抽象方法
  7. 正则表达式匹配两个特殊字符中间的内容
  8. django.core.exceptions.ImproperlyConfigured: Requested setting DEFAULT_INDEX_TABLESPACE的解决办法(转)...
  9. 16.实现多个具有相同方法的接口和父类与实现接口有相同方法
  10. 关于string.Template的简单介绍