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

加入VIP,免费下载
 

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

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

下载须知

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

版权提示 | 免责声明

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

Java集合ArrayList的实现原理Word文档格式.docx

1、 private transient Object elementData; * The size of the ArrayList (the number of elements it contains). * * serial private int size;elementData存储ArrayList内的元素,size表示它包含的元素的数量。有个关键字需要解释:transient。Java的serialization提供了一种持久化对象实例的机制。当持久化对象时,可能有一个特殊的对象数据成员,我们不想用serialization机制来保存它。为了在一个特定对象的一个域上关闭serial

2、ization,可以在这个域前加上关键字transient。构造方法ArrayList提供了三种方式的构造器,可以构造一个默认初始容量为10的空列表、构造一个指定初始容量的空列表以及构造一个包含指定collection的元素的列表,这些元素按照该collection的迭代器返回它们的顺序排列的。 * Constructs an empty list with the specified initial capacity. * param initialCapacity the initial capacity of the list * throws IllegalArgumentExcept

3、ion if the specified initial capacity * is negative public ArrayList(int initialCapacity) super(); if (initialCapacity 0) throw new IllegalArgumentException(Illegal Capacity: + initialCapacity); this.elementData = new ObjectinitialCapacity; * Constructs an empty list with an initial capacity of ten.

4、 public ArrayList() this.elementData = EMPTY_ELEMENTDATA; * Constructs a list containing the elements of the specified * collection, in the order they are returned by the collections * iterator. * param c the collection whose elements are to be placed into this list * throws NullPointerException if

5、the specified collection is null public ArrayList(Collection c) elementData = c.toArray(); size = elementData.length; / c.toArray might (incorrectly) not return Object (see 6260652) if (elementData.getClass() != Object.class) elementData = Arrays.copyOf(elementData, size, Object.class);元素存储ArrayList

6、提供了set(int index, E element)、add(E e)、add(int index, E element)、addAll(Collection/ 用指定的元素替代此列表中指定位置上的元素,并返回以前位于该位置上的元素。public E set(int index, E element) RangeCheck(index); /范围检查 E oldValue = (E) elementDataindex; elementDataindex = element; return oldValue; / 将指定的元素添加到此列表的尾部。public boolean add(E e)

7、 ensureCapacity(size + 1); elementDatasize+ = e; return true;/ 将指定的元素插入此列表中的指定位置。/ 如果当前位置有元素,则向右移动当前位于该位置的元素以及所有后续元素(将其索引加1)。public void add(int index, E element) if (index size | index 0) throw new IndexOutOfBoundsException(Index:+index+, Size:+size); / 如果数组长度不足,将进行扩容。 ensureCapacity(size+1); / Inc

8、rements modCount! / 将 elementData中从Index位置开始、长度为size-index的元素, / 拷贝到从下标为index+1位置开始的新的elementData数组中。 / 即将当前位于该位置的元素以及所有后续元素右移一个位置。 System.arraycopy(elementData, index, elementData, index + 1, size - index); size+;/ 按照指定collection的迭代器所返回的元素顺序,将该collection中的所有元素添加到此列表的尾部。public boolean addAll(Collect

9、ion c) Object a = c.toArray(); int numNew = a.length; ensureCapacity(size + numNew); / Increments modCount System.arraycopy(a, 0, elementData, size, numNew); size += numNew; return numNew != 0;/ 从指定的位置开始,将指定collection中的所有元素插入到此列表中。public boolean addAll(int index, Collection System.arraycopy(elementD

10、ata, index, elementData, index + numNew, numMoved); System.arraycopy(a, 0, elementData, index, numNew);元素读取/ 返回此列表中指定位置上的元素。 public E get(int index) return (E) elementDataindex;元素删除romove(int index):/ 移除此列表中指定位置上的元素。 public E remove(int index) modCount+; int numMoved = size - index - 1; System.array

11、copy(elementData, index+1, elementData, index, numMoved); elementData-size = null; / Let gc do its work 首先是检查范围,修改modCount,保留将要被移除的元素,将移除位置之后的元素向前挪动一个位置,将list末尾元素置空(null),返回被移除的元素。remove(Object o)/ 移除此列表中首次出现的指定元素(如果存在)。这是应为ArrayList中允许存放重复的元素。 public boolean remove(Object o) / 由于ArrayList中允许存放null,

12、因此下面通过两种情况来分别处理。 if (o = null) for (int index = 0; index size; index+) if (elementDataindex = null) / 类似remove(int index),移除列表中指定位置上的元素。 fastRemove(index); else if (o.equals(elementDataindex) return false;首先通过代码可以看到,当移除成功后返回true,否则返回false。remove(Object o)中通过遍历element寻找是否存在传入对象,一旦找到就调用fastRemove移除对象。

13、为什么找到了元素就知道了index,不通过remove(index)来移除元素呢?因为fastRemove跳过了判断边界的处理,因为找到元素就相当于确定了index不会超过边界,而且fastRemove并不返回被移除的元素。下面是fastRemove的代码,基本和remove(index)一致。private void fastRemove(int index) System.arraycopy(elementData, index+1, elementData, index, numMoved);removeRange(int fromIndex,int toIndex)protected

14、void removeRange(int fromIndex, int toIndex) int numMoved = size - toIndex; System.arraycopy(elementData, toIndex, elementData, fromIndex, int newSize = size - (toIndex-fromIndex); while (size != newSize) 执行过程是将elementData从toIndex位置开始的元素向前移动到fromIndex,然后将toIndex位置之后的元素全部置空顺便修改size。这个方法是protected,及受保

15、护的方法,为什么这个方法被定义为protected呢?这是一个解释,但是可能不容易看明白。先看下面这个例子: ArrayList ints = new ArrayList oldCacity) Object oldData = elementData; int newCapacity = (oldCapacity * 3)/2 + 1; /增加50%+1 if (newCapacity minCapacity) newCapacity = minCapacity; / minCapacity is usually close to size, so this is a win: element

16、Data = Arrays.copyOf(elementData, newCapacity);从上述代码中可以看出,数组进行扩容时,会将老数组中的元素重新拷贝一份到新的数组中,每次数组容量的增长大约是其原容量的1.5倍。这种操作的代价是很高的,因此在实际使用时,我们应该尽量避免数组容量的扩张。当我们可预知要保存的元素的多少时,要在构造ArrayList实例时,就指定其容量,以避免数组扩容的发生。或者根据实际需求,通过调用ensureCapacity方法来手动增加ArrayList实例的容量。Object oldData = elementData;/为什么要用到oldData 乍一看来后面并没

17、有用到关于oldData, 这句话显得多此一举!但是这是一个牵涉到内存管理的类, 所以要了解内部的问题。 而且为什么这一句还在if的内部,这跟elementData = Arrays.copyOf(elementData, newCapacity); 这句是有关系的,下面这句Arrays.copyOf的实现时新创建了newCapacity大小的内存,然后把老的elementData放入。好像也没有用到oldData,有什么问题呢。问题就在于旧的内存的引用是elementData, elementData指向了新的内存块,如果有一个局部变量oldData变量引用旧的内存块的话,在copy的过程中

18、就会比较安全,因为这样证明这块老的内存依然有引用,分配内存的时候就不会被侵占掉,然后copy完成后这个局部变量的生命期也过去了,然后释放才是安全的。不然在copy的的时候万一新的内存或其他线程的分配内存侵占了这块老的内存,而copy还没有结束,这将是个严重的事情。关于ArrayList和Vector区别如下:ArrayList在内存不够时默认是扩展50% + 1个,Vector是默认扩展1倍。Vector提供indexOf(obj, start)接口,ArrayList没有。Vector属于线程安全级别的,但是大多数情况下不使用Vector,因为线程安全需要更大的系统开销。ArrayList还

19、给我们提供了将底层数组的容量调整为当前列表保存的实际元素的大小的功能。它可以通过trimToSize方法来实现。代码如下:public void trimToSize() if (size oldCapacity) elementData = Arrays.copyOf(elementData, size);由于elementData的长度会被拓展,size标记的是其中包含的元素的个数。所以会出现size很小但elementData.length很大的情况,将出现空间的浪费。trimToSize将返回一个新的数组给elementData,元素内容保持不变,length和size相同,节省空间。

20、转为静态数组toArray注意ArrayList的两个转化为静态数组的toArray方法。第一个, 调用Arrays.copyOf将返回一个数组,数组内容是size个elementData的元素,即拷贝elementData从0至size-1位置的元素到新数组并返回。public Object toArray() return Arrays.copyOf(elementData, size);第二个,如果传入数组的长度小于size,返回一个新的数组,大小为size,类型与传入数组相同。所传入数组长度与size相等,则将elementData复制到传入数组中并返回传入的数组。若传入数组长度大于s

21、ize,除了复制elementData外,还将把返回数组的第size个元素置为空。public T toArray(T a) if (a.length asize = null; return a;总结:关于ArrayList的源码,给出几点比较重要的总结:1、注意其三个不同的构造方法。无参构造方法构造的ArrayList的容量默认为10,带有Collection参数的构造方法,将Collection转化为数组赋给ArrayList的实现数组elementData。2、注意扩充容量的方法ensureCapacity。ArrayList在每次增加元素(可能是1个,也可能是一组)时,都要调用该方法来确保足够的容量。当容量不足以容纳当前的元素个数时,就设置新的容量为旧的容量的1.5倍加1,如果设置后的新容量还不够,则直接新容量设置为传入的参数(也就是所需的容量),而后用Arrays.copyof()方法将元素拷贝到新的数组(详见下面的第3点)。从中可以看出,当容量不够时,每次增加元素,都要将原来的元素拷贝到一

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

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