一、层级关系 二、初始化方式
(1)Listlist = new ArrayList<>(); public ArrayList() { this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; } private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
第一个结论:ArrayList底层是数组
第二个结论:若用无参构造器的方式实例化ArrayList,只是声明了数组,还未分配空间
(2)Listlist = new ArrayList<>(10); public ArrayList(int initialCapacity) { if (initialCapacity > 0) { this.elementData = new Object[initialCapacity]; } else if (initialCapacity == 0) { this.elementData = EMPTY_ELEMENTDATA; } else { throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } } private static final Object[] EMPTY_ELEMENTDATA = {};
补充第二结论:若用有参构造器的方式实例化ArrayList且initialCapacity大于0,则既声明了数组,也分配了空间
三、基本方法的使用 add流程图
源码解析
public boolean add(E e) { //校验数组容量,若空间不够则扩容复制生成一个新的数组 ensureCapacityInternal(size + 1); //赋值 elementData[size++] = e; return true; } private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); } /** * 若数组是通过无参构造器的方式实例化的话,返回的minCapacity为10,最后会通过grow方法复制生成一个大小为10的数组 * 若数组是通过有参构造器的方式实例化的话,返回的minCapacity为当前要操作的数组下标,不建议声明小于10的数组空间,因为这样前几次add都要去扩容复制生成一个新的数组 */ private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); } //扩容大小:原数组大小 + 原数组大小/2 private void grow(int minCapacity) { // overflow-conscious code int 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); }
其它说明
初始化ArrayList时,不建议声明小于10的容量,因为这样前几次add都要去扩容复制生成一个新的数组
Arrays.copyOf(T[] original, int newLength):该方法会创建一个新的数组
remove流程图
源码解析
public E remove(int index) { //检查index是否 >= size,若大于则报数组越界异常 rangeCheck(index); modCount++; E oldValue = elementData(index); int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); elementData[--size] = null; // clear to let GC do its work return oldValue; }
其它说明
System.arraycopy - 浅复制
public static void arraycopy( Object src, //源数组 int srcPos, //源数组要复制的起始位置 Object dest, //目标数组 int destPos, //目的数组放置的起始位置 int length //复制长度 )四、补充
ArrayList是线程不安全的,表现在多线程下add和remove可能会发生数组越界
不要在foreach循环里进行元素的remove/add操作。remove元素请使用Iterator方式,如果并发操作,需要对Iterator对象加锁
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/71558.html
摘要:自定义类的概述自定义类的概述代码映射成现实事物的过程就是定义类的过程。自定义类的格式自定义类的格式使用类的形式对现实中的事物进行描述。 01引用数据类型_类 * A: 数据类型 * a: java中的数据类型分为:基本类型和引用类型 * B: 引用类型的分类 * a: Java为我们提供好的类,比如说:Scanner,Random等。 * b: 我们自己创建的类...
摘要:需要注意的是,通过构造函数定义初始量是动态数组的实际大小。带容量的构造函数新建一个容量为的数组默认构造函数,默认为空构造一个包含指定元素的第一个构造方法使用提供的来初始化数组的大小。 前言 今天介绍经常使用的一个Java集合类——ArrayList(基于JDK1.8.0_121)。ArrayList在工作和日常面试中经常被使用或者提到。总的来说,工作中使用ArrayList主要是因为动...
摘要:第三阶段常见对象的学习集合框架接口按照集合框架的继承体系,我们先从中的接口开始学习一概述及功能演示概述在中充当着一个什么样的身份呢有序的也称为序列实现这个接口的用户以对列表中每个元素的插入位置进行精确地控制。线程不安全,效率高。 第三阶段 JAVA常见对象的学习 集合框架——List接口 showImg(https://segmentfault.com/img/remote/14600...
摘要:集合代表一个元素有序可重复的集合,集合中每个元素都有其对应的顺序索引。集合默认按元素的添加顺序设置元素的索引。 List集合代表一个元素有序、可重复的集合,集合中每个元素都有其对应的顺序索引。List集合可以通过索引来访问指定位置的集合元素。List集合默认按元素的添加顺序设置元素的索引。 Java8改进的List接口和ListIterator接口 普通方法 List是有序集合,因此L...
摘要:用户自己指定容量创建大小的数组创建空数组默认构造函数,其默认初始容量为构造一个包含指定集合的元素的列表,按照它们由集合的迭代器返回的顺序。以正确的顺序返回该列表中的元素的迭代器。此方法充当基于阵列和基于集合的之间的桥梁。 目录: 0-0-1. 前言 0-0-2. 集合框架知识回顾 0-0-3. ArrayList简介 0-0-4. ArrayList核心源码 0-0-5. Ar...
阅读 3214·2021-09-22 16:06
阅读 3211·2021-09-02 15:40
阅读 607·2019-08-30 15:54
阅读 1014·2019-08-26 12:22
阅读 1347·2019-08-26 12:17
阅读 2727·2019-08-26 12:09
阅读 435·2019-08-26 10:20
阅读 760·2019-08-23 16:28