ImageVerifierCode 换一换
格式:DOCX , 页数:27 ,大小:30.66KB ,
资源ID:6074158      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/6074158.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(java面试 集合中知识点 ArrayList源码+扩容机制分析 整理.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

java面试 集合中知识点 ArrayList源码+扩容机制分析 整理.docx

1、java面试 集合中知识点 ArrayList源码+扩容机制分析 整理1. ArrayList 简介ArrayList 的底层是数组队列,相当于动态数组。与 Java 中的数组相比,它的容量能动态增长。在添加大量元素前,应用程序可以使用ensureCapacity操作来增加 ArrayList 实例的容量。这可以减少递增式再分配的数量。ArrayList继承于 AbstractList ,实现了 List, RandomAccess, Cloneable, java.io.Serializable 这些接口。public class ArrayList extends AbstractList

2、 implements List, RandomAccess, Cloneable, java.io.Serializable RandomAccess 是一个标志接口,表明实现这个这个接口的 List 集合是支持快速随机访问的。在 ArrayList 中,我们即可以通过元素的序号快速获取元素对象,这就是快速随机访问。ArrayList 实现了 Cloneable 接口 ,即覆盖了函数clone(),能被克隆。ArrayList 实现了 java.io.Serializable接口,这意味着ArrayList支持序列化,能通过序列化去传输。1.1. Arraylist 和 Vector 的区别

3、?1.ArrayList 是 List 的主要实现类,底层使用 Object 存储,适用于频繁的查找工作,线程不安全 ;2.Vector 是 List 的古老实现类,底层使用 Object 存储,线程安全的。1.2. Arraylist 与 LinkedList 区别?3.是否保证线程安全: ArrayList 和 LinkedList 都是不同步的,也就是不保证线程安全;4.底层数据结构: Arraylist 底层使用的是 Object 数组;LinkedList 底层使用的是 双向链表 数据结构(JDK1.6 之前为循环链表,JDK1.7 取消了循环。注意双向链表和双向循环链表的区别,下面

4、有介绍到!)5.插入和删除是否受元素位置的影响: ArrayList 采用数组存储,所以插入和删除元素的时间复杂度受元素位置的影响。 比如:执行add(E e)方法的时候, ArrayList 会默认在将指定的元素追加到此列表的末尾,这种情况时间复杂度就是 O(1)。但是如果要在指定位置 i 插入和删除元素的话(add(int index, E element))时间复杂度就为 O(n-i)。因为在进行上述操作的时候集合中第 i 和第 i 个元素之后的(n-i)个元素都要执行向后位/向前移一位的操作。 LinkedList 采用链表存储,所以对于add(E e)方法的插入,删除元素时间复杂度不

5、受元素位置的影响,近似 O(1),如果是要在指定位置i插入和删除元素的话((add(int index, E element)) 时间复杂度近似为o(n)因为需要先移动到指定位置再插入。6.是否支持快速随机访问: LinkedList 不支持高效的随机元素访问,而 ArrayList 支持。快速随机访问就是通过元素的序号快速获取元素对象(对应于get(int index)方法)。7.内存空间占用: ArrayList 的空 间浪费主要体现在在 list 列表的结尾会预留一定的容量空间,而 LinkedList 的空间花费则体现在它的每一个元素都需要消耗比 ArrayList 更多的空间(因为要

6、存放直接后继和直接前驱以及数据)。2. ArrayList 核心源码解读package java.util;import java.util.function.Consumer;import java.util.function.Predicate;import java.util.function.UnaryOperator;public class ArrayList extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializable private static final long se

7、rialVersionUID = 8683452581122892189L; /* * 默认初始容量大小 */ private static final int DEFAULT_CAPACITY = 10; /* * 空数组(用于空实例)。 */ private static final Object EMPTY_ELEMENTDATA = ; /用于默认大小空实例的共享空数组实例。 /我们把它从EMPTY_ELEMENTDATA数组中区分出来,以知道在添加第一个元素时容量需要增加多少。 private static final Object DEFAULTCAPACITY_EMPTY_ELE

8、MENTDATA = ; /* * 保存ArrayList数据的数组 */ transient Object elementData; / non-private to simplify nested class access /* * ArrayList 所包含的元素个数 */ private int size; /* * 带初始容量参数的构造函数(用户可以在创建ArrayList对象时自己指定集合的初始大小) */ public ArrayList(int initialCapacity) if (initialCapacity 0) /如果传入的参数大于0,创建initialCapaci

9、ty大小的数组 this.elementData = new ObjectinitialCapacity; else if (initialCapacity = 0) /如果传入的参数等于0,创建空数组 this.elementData = EMPTY_ELEMENTDATA; else /其他情况,抛出异常 throw new IllegalArgumentException(Illegal Capacity: + initialCapacity); /* *默认无参构造函数 *DEFAULTCAPACITY_EMPTY_ELEMENTDATA 为0.初始化为10,也就是说初始其实是空数组

10、当添加第一个元素的时候数组容量才变成10 */ public ArrayList() this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; /* * 构造一个包含指定集合的元素的列表,按照它们由集合的迭代器返回的顺序。 */ public ArrayList(Collection c) /将指定集合转换为数组 elementData = c.toArray(); /如果elementData数组的长度不为0 if (size = elementData.length) != 0) / 如果elementData不是Object类型数据(c.

11、toArray可能返回的不是Object类型的数组所以加上下面的语句用于判断) if (elementData.getClass() != Object.class) /将原来不是Object类型的elementData数组的内容,赋值给新的Object类型的elementData数组 elementData = Arrays.copyOf(elementData, size, Object.class); else / 其他情况,用空数组代替 this.elementData = EMPTY_ELEMENTDATA; /* * 修改这个ArrayList实例的容量是列表的当前大小。 应用程序

12、可以使用此操作来最小化ArrayList实例的存储。 */ public void trimToSize() modCount+; if (size minExpand) ensureExplicitCapacity(minCapacity); /得到最小扩容量 private void ensureCapacityInternal(int minCapacity) if (elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA) / 获取“默认的容量”和“传入参数”两者之间的最大值 minCapacity = Math.max(DEFAULT_CAPA

13、CITY, minCapacity); ensureExplicitCapacity(minCapacity); /判断是否需要扩容 private void ensureExplicitCapacity(int minCapacity) modCount+; / overflow-conscious code if (minCapacity - elementData.length 0) /调用grow方法进行扩容,调用此方法代表已经开始扩容了 grow(minCapacity); /* * 要分配的最大数组大小 */ private static final int MAX_ARRAY_S

14、IZE = Integer.MAX_VALUE - 8; /* * ArrayList扩容的核心方法。 */ private void grow(int minCapacity) / oldCapacity为旧容量,newCapacity为新容量 int oldCapacity = elementData.length; /将oldCapacity 右移一位,其效果相当于oldCapacity /2, /我们知道位运算的速度远远快于整除运算,整句运算式的结果就是将新容量更新为旧容量的1.5倍, int newCapacity = oldCapacity + (oldCapacity 1); /

15、然后检查新容量是否大于最小需要容量,若还是小于最小需要容量,那么就把最小需要容量当作数组的新容量, if (newCapacity - minCapacity 0) newCapacity = hugeCapacity(minCapacity); / minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); /比较minCapacity和 MAX_ARRAY_SIZE private static int hugeCapacity(

16、int minCapacity) if (minCapacity MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; /* *返回此列表中的元素数。 */ public int size() return size; /* * 如果此列表不包含元素,则返回 true 。 */ public boolean isEmpty() /注意=和=的区别 return size = 0; /* * 如果此列表包含指定的元素,则返回true 。 */ public boolean contains(Object o) /indexOf()方法:返回此

17、列表中指定元素的首次出现的索引,如果此列表不包含此元素,则为-1 return indexOf(o) = 0; /* *返回此列表中指定元素的首次出现的索引,如果此列表不包含此元素,则为-1 */ public int indexOf(Object o) if (o = null) for (int i = 0; i size; i+) if (elementDatai=null) return i; else for (int i = 0; i = 0; i-) if (elementDatai=null) return i; else for (int i = size-1; i = 0;

18、 i-) if (o.equals(elementDatai) return i; return -1; /* * 返回此ArrayList实例的浅拷贝。 (元素本身不被复制。) */ public Object clone() try ArrayList v = (ArrayList) super.clone(); /Arrays.copyOf功能是实现数组的复制,返回复制后的数组。参数是被复制的数组和复制的长度 v.elementData = Arrays.copyOf(elementData, size); v.modCount = 0; return v; catch (CloneNo

19、tSupportedException e) / 这不应该发生,因为我们是可以克隆的 throw new InternalError(e); /* *以正确的顺序(从第一个到最后一个元素)返回一个包含此列表中所有元素的数组。 *返回的数组将是“安全的”,因为该列表不保留对它的引用。 (换句话说,这个方法必须分配一个新的数组)。 *因此,调用者可以自由地修改返回的数组。 此方法充当基于阵列和基于集合的API之间的桥梁。 */ public Object toArray() return Arrays.copyOf(elementData, size); /* * 以正确的顺序返回一个包含此列表中

20、所有元素的数组(从第一个到最后一个元素); *返回的数组的运行时类型是指定数组的运行时类型。 如果列表适合指定的数组,则返回其中。 *否则,将为指定数组的运行时类型和此列表的大小分配一个新数组。 *如果列表适用于指定的数组,其余空间(即数组的列表数量多于此元素),则紧跟在集合结束后的数组中的元素设置为null 。 *(这仅在调用者知道列表不包含任何空元素的情况下才能确定列表的长度。) */ SuppressWarnings(unchecked) public T toArray(T a) if (a.length size) asize = null; return a; / Position

21、al Access Operations SuppressWarnings(unchecked) E elementData(int index) return (E) elementDataindex; /* * 返回此列表中指定位置的元素。 */ public E get(int index) rangeCheck(index); return elementData(index); /* * 用指定的元素替换此列表中指定位置的元素。 */ public E set(int index, E element) /对index进行界限检查 rangeCheck(index); E oldVa

22、lue = elementData(index); elementDataindex = element; /返回原来在这个位置的元素 return oldValue; /* * 将指定的元素追加到此列表的末尾。 */ public boolean add(E e) ensureCapacityInternal(size + 1); / Increments modCount! /这里看到ArrayList添加元素的实质就相当于为数组赋值 elementDatasize+ = e; return true; /* * 在此列表中的指定位置插入指定的元素。 *先调用 rangeCheckForA

23、dd 对index进行界限检查;然后调用 ensureCapacityInternal 方法保证capacity足够大; *再将从index开始之后的所有成员后移一个位置;将element插入index位置;最后size加1。 */ public void add(int index, E element) rangeCheckForAdd(index); ensureCapacityInternal(size + 1); / Increments modCount! /arraycopy()这个实现数组之间复制的方法一定要看一下,下面就用到了arraycopy()方法实现数组自己复制自己 S

24、ystem.arraycopy(elementData, index, elementData, index + 1, size - index); elementDataindex = element; size+; /* * 删除该列表中指定位置的元素。 将任何后续元素移动到左侧(从其索引中减去一个元素)。 */ public E remove(int index) rangeCheck(index); modCount+; E oldValue = elementData(index); int numMoved = size - index - 1; if (numMoved 0) S

25、ystem.arraycopy(elementData, index+1, elementData, index, numMoved); elementData-size = null; / clear to let GC do its work /从列表中删除的元素 return oldValue; /* * 从列表中删除指定元素的第一个出现(如果存在)。 如果列表不包含该元素,则它不会更改。 *返回true,如果此列表包含指定的元素 */ public boolean remove(Object o) if (o = null) for (int index = 0; index size; index+) if (elementDataindex = null) fastRemove(index); return true; else for (int index = 0; index size; index+) if (o.equals(el

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1