一、ArrayList的注意事项:

1)ArrayList可以放任何元素,包括空值,可以加入多个空值。
2)ArrayList是由数组来实现数据存储的
3)ArrayList基本等同于Vector,除lArrayList是线程不安全(执行效率高),在多线程情况下,不建议使用ArrayList
没有synchronized进行修饰

二、ArrayList 的底层操作机制源码分析(重点,难点)

  • ArrayList 中维护了一个 Object类型的数组 elementData。 transient Object[]
    elementData; // transient 标识瞬间,短暂的,表示该属性不会被序列化
  • 当创建ArrayList对象时,如果使用的是无参构造器,则初始elementData
    容量为0,第一次添加,则扩容elementData为10,如需再次扩容,则扩容elementData为1.5倍。
  • 如果使用的是指定大小的构造器,则初始elementData容量为指定大小,如果需要扩容,则直接扩容elementData为1.5倍。
// 关闭警告
@SuppressWarnings({"all"})
public class ArrayListSource {public static void main(String[] args) {//      源码分析
//      使用无参构造器创建ArrayList对象ArrayList list = new ArrayList();
//      使用for循环给list集合添加 1-10 数据for (int i = 0; i <= 10; i++) {list.add(i);}
//      使用for循环给list集合添加 11-15 数据for (int i = 11; i<=15;i++){list.add(i);}list.add(100);list.add(200);list.add(null);for (Object o : list) {System.out.println(o);}}
}
  • 在 ArrayList list = new ArrayList(); 处添加断点
  • debug – step Into 到 ArrayList.java的ArrarList()构造方法
  • 使用无参构造器
/*** Constructs an empty list with an initial capacity of ten.*/public ArrayList() {this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;}
  • 查询DEFAULTCAPACITY_EMPTY_ELEMENTDATA可发现 默认为空数组
/*** Shared empty array instance used for default sized empty instances. We* distinguish this from EMPTY_ELEMENTDATA to know how much to inflate when* first element is added.*/private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

然后执行 list 的boolean add(E e)方法
先确定是否要扩容,
然后再执行 赋值

/*** Appends the specified element to the end of this list.** @param e element to be appended to this list* @return <tt>true</tt> (as specified by {@link Collection#add})*/public boolean add(E e) {ensureCapacityInternal(size + 1);  // Increments modCount!!elementData[size++] = e;return true;}

在boolean add(E e)方法中,先执行ensureCapacityInternal(size + 1)方法确定是否要扩容,然后再执行赋值。

private void ensureCapacityInternal(int minCapacity) {ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));}

在calculateCapacity()方法中 先确定elementData是否为空数组,如果为空数组,返回DEFAULT_CAPACITY(默认为10) 和 minCapacity(第一次为1) 中的最大值,

private static int calculateCapacity(Object[] elementData, int minCapacity) {if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {return Math.max(DEFAULT_CAPACITY, minCapacity);}return minCapacity;}

在ensureExplicitCapacity(int minCapacity)方法中确定是否真的扩容

modCount++ :记录集合修改次数
如果elementData大小不够,则调用grow()进行扩容

minCapacity - elementData.length > 0 :如果数组所需最小容量 - 数组当前实际大小 大于 0 则执行扩容

private void ensureExplicitCapacity(int minCapacity) {modCount++;// overflow-conscious codeif (minCapacity - elementData.length > 0)grow(minCapacity);}

grow()方法执行扩容

  • 将elementData.length 记录到 oldCapacity中,第一次值为0 newCapacity = oldCapacity
  • (oldCapacity >> 1); 执行扩容,扩容大小为 数组当前容量+数组当前大小右移1位(除以2),即扩容1.5倍
  • 因为第一次扩容oldCapacity 为0 所有newCapacity 也为0,执行 if (newCapacity -
    minCapacity < 0) newCapacity = minCapacity; 此时newCapacity 为
    10,所以第一次扩容大小为 10
  • elementData = Arrays.copyOf(elementData, newCapacity);
    Arrays.copyOf()方法可保留原先数据扩容 执行Arrays.copyOf()方法进行扩容,第一次执行完elementData
    中有10个空数据
/*** Increases the capacity to ensure that it can hold at least the* number of elements specified by the minimum capacity argument.** @param minCapacity the desired minimum capacity*/private void grow(int minCapacity) {// overflow-conscious codeint oldCapacity = elementData.length;int newCapacity = oldCapacity + (oldCapacity >> 1);if (newCapacity - minCapacity < 0)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);}

扩容完成后,继续执行add()方法,将数据添加到elementData数组中

集合-ArrayList相关推荐

  1. Java ArrayList和Vector、LinkedList与ArrayList、数组(Array)和列表集合(ArrayList)的区别...

    ArrayList和Vector的区别 ArrayList与Vector主要从二方面来说. 一.同步性: Vector是线程安全的,也就是说是同步的,而ArrayList是线程序不安全的,不是同步的. ...

  2. C#方法,可空类型,数组,集合,ArrayList排序,List,Hashtable和Dictionary

    C#方法 方法的定义: public void/int Compare(int a,int b){ } Program program = new Program(); Console.WriteLi ...

  3. 第九天 (集合 ArrayList)

    目录 集合 ArrayList 创建集合的对象 ArrayList成员方法 集合 集合和数组的对比 1.长度: 集合自动伸缩,可长可短,自动扩容. 数组长度固定. 2.存储类型: 集合可以存储引用数据 ...

  4. java集合-ArrayList

    java集合 ArrayList Iterable Comparable(排序接口) 项目结构: class Dog implements Comparable<Dog> {private ...

  5. Java学习——集合ArrayList类

    1,集合ArrayList类底层就是用数组来实现的,其语法为: ArrayList objectName =new ArrayList<>(); 这个E一定要用引用数据类型 2,集合跟数组 ...

  6. Java集合—ArrayList底层原理

    原文作者:0 errors 0 warnings 原文地址:用大白话告诉你ArrayList的底层原理 目录 一.数据结构 二.线程安全性 三.继承关系 四.构造方法 五.add()方法 六.扩容机制 ...

  7. Java集合-ArrayList源码解析-JDK1.8

    ◆ ArrayList简介 ◆ ArrayList 是一个数组队列,相当于 动态数组.与Java中的数组相比,它的容量能动态增长.它继承于AbstractList,实现了List, RandomAcc ...

  8. List集合ArrayList,LinkList

    1.List是Collection子接口,拥有其所有方法. 2.List是有序集合,集合中每个元素都有对应顺序序列.List集合可使用重复元素,可以通过索引来访问指定位置的集合元素(顺序索引从0开始) ...

  9. JAVA复习5(集合——ArrayList)

    集合 所谓集合指的就是一套动态对象数组,在实际开发中数组的概念的一定会使用的,但是数组的问题是一旦开辟空间则长度不可改变 其实就是对数据结构的一种封装,用户不用去编写,直接使用. 由于数据结构开发起来 ...

最新文章

  1. Mysql学习总结(41)——MySql数据库基本语句再体会
  2. Android进阶:六、在子线程中直接使用 Toast 及其原理
  3. oracle LPDA,oracle中自动增长列的设置
  4. 爬虫-urlparse与urlsplit
  5. 【转】java基础知识总结
  6. linux防火墙保存报错,29.Linux防火墙-firewalled
  7. 你看那个人他像一条狗
  8. Angular和Vue.js 深度对比
  9. 杨辉三角形Python实现
  10. 2015年蓝桥杯A组C/C++ 第三题奇妙的数字
  11. PHP 微信小程序生成二维码
  12. 马尔可夫链模型的信贷风险分析与预测
  13. 手把手系列--STM32H750移植FreeRTOS(二)--优化编译速度
  14. 战国破坏神引擎全面升级 游戏画质大幅提升
  15. P背景软件测试,软件测试的背景和发展
  16. Latex ulem包设置下划线删除线强调文本等效果
  17. 推荐模型-上下文感知-2016:FNN模型【FM家族】【FM+MLP=FNN】
  18. 学计算机会学dos,DOS操作系统和上课学习的应用软件_CPUCPU评测-中关村在线
  19. log4j2输出中文乱码
  20. 如何快速设计一款门磁传感器产品?App即可确认门窗关闭

热门文章

  1. ae的渲染引擎:cineware
  2. 我的思维模式的阿喀琉斯之踵
  3. 如何设计一个 RPC 系统
  4. 前端基础(一):js数据类型
  5. java基础:简单实现线程池
  6. 中科点击矩阵式推进大数据落地与应用
  7. 自动批量修改linux用户密码
  8. JavaScript之match()方法讲解
  9. hdu- 2642 Stars 二维树状数组
  10. Android 近百个项目的源代码,覆盖Android开发的每个领域