今天电话面试,面试官问到ArrayList中add方法的原理,我一下蒙了,这个用的最多的一种数据结构被我忽视了,没答上来,有时候用的最多的反而最自信,最自信的东西最容易忽视其中的细节,因此今天决定扒扒源码。
一种用来存放数据的数据结构。
它的底层是一个数组,用来存放数据。
源码比较多的,我另开博客做了解读,源码较短较简单的,我直接说明了源码的作用。
源码类型 | 源码概览 | 源码分析 |
---|---|---|
属性 | private static final long serialVersionUID = 8683452581122892189L; | 序列化时用来验证数据一致性的值 |
属性 | private static final int DEFAULT_CAPACITY = 10; | 空参构造初始化数组时,数组的默认大小为10 |
属性 | private static final Object[] EMPTY_ELEMENTDATA = {}; | 一个空的数组 |
属性 | private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; | 共享空数组实例,用于默认大小的空实例。我们将其与DEFAULTCAPACITY_EMPTY_ELEMENTDATA分开来,以了解添加第一个元素时要扩容多少。 |
属性 | transient Object[] elementData; | 一个临时使用的数组 |
属性 | private int size; | 当前数组里所存放元素的个数 |
方法 | public ArrayList(int initialCapacity) {} | 有参的构造方法,指定数组的初始容量大小 |
方法 | public ArrayList() {} | 默认的空参构造。默认的初始化容量大小为10 |
方法 | public ArrayList(Collection extends E> c) {} | 按照入参集合的迭代器返回的元素的顺序构造包含指定集合的元素的数组。 |
方法 | public void trimToSize() {} | 把数组的容量变为当前数组中包含元素的大小,此方法用来最小化数组在存储空间所占用的大小。 |
方法 | public void ensureCapacity(int minCapacity) {} | 用来在添加数据时,保证数组容量大于数组所包含的元素个数的。 |
方法 | private void ensureCapacityInternal(int minCapacity) {} | 当数组为空数组时,最小容量设置为传入的参数,并且最后调用函数(下一行) |
方法 | private void ensureExplicitCapacity(int minCapacity) {} | 增加一次修改数组的次数,修改数组后,容量若小于数组元素个数,开始扩容。 |
属性 | private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; | 能分配的数组最大的大小。某些虚拟机在数组中保留一些头字。尝试分配较大的数组可能导致内存不足错误:请求的数组大小超过了VM限制,因此数组的最大容量 MAX_ARRAY_SIZE要在Integer.MAX_VALUE上要减去8个!!Integer.MAX_VALUE为 |
方法 | private void grow(int minCapacity) {} | https://blog.csdn.net/qq_29519041/article/details/86246881 |
方法 | private static int hugeCapacity(int minCapacity) {} | https://blog.csdn.net/qq_29519041/article/details/86246881 |
方法 | public int size() {} | 返回数组中存放的元素个数 |
方法 | public boolean isEmpty() {} | 当数组中没有元素时 返回true 否者为false |
方法 | public boolean contains(Object o) {} | 作用:判断数组中是否包含 o 对象,原理:调用了indexOf做判断。看下一行 |
方法 | public int indexOf(Object o) {} | https://blog.csdn.net/qq_29519041/article/details/86259595 就是普通的遍历查找,并返回下标。 |
方法 | public int lastIndexOf(Object o) {} | 与indexOf方法的唯一区别是,遍历从尾部开始。其他和indexOf完全一样。 |
方法 | public Object clone() {} | 浅拷贝!,就是对一个对象只复制他们对应的引用,这些复制后的引用指向的还是之前的对象。就是说,对象的实例只有一个。但是有两个引用指向他们。我自己的理解。若有错误请留言 关于深拷贝浅拷贝相关优秀博文: https://blog.csdn.net/github_38687585/article/details/79926909 https://blog.csdn.net/DeMonliuhui/article/details/54572908 |
方法 | public Object[] toArray() {} | 返回包含此列表中所有元素的数组。 (从第一个元素到最后一个元素)。 返回的数组将是“安全的”,因为此列表不维护对它的引用。(换句话说,此方法必须分配一个新数组)。 因此,调用方可以自由修改返回的数组。 此方法充当基于数组和基于集合的API之间的桥梁。 |
方法 | public |
https://rogerfederer.iteye.com/blog/788795
它与上面的方法的区别是,它会以传入的数组的类型来返回对应类型的数组。 |
方法 | E elementData(int index) {} | 返回数组索引位置的元素,它将会被get(int index)调用 |
方法 | public E get(int index) {} | 返回数组索引位置的元素,首先会调用rangeCheck判断是否数组索引越界,之后调用elementData(int index)方法。 |
方法 | public E set(int index, E element) {} | 把element替换掉index位置的元素,并返回被替换掉的元素 |
方法 | public boolean add(E e) {} | 在尾部添加元素,之前会对元素修改次数做累加。 |
方法 | public void add(int index, E element) {} | 在数组相应位置添加元素,对应位置及以后的元素向后移一位,这也是数组插入数据慢的原因。需要移动后面的元素。 |
方法 | public E remove(int index) {} | https://blog.csdn.net/qq_29519041/article/details/86316290 |
方法 | public boolean remove(Object o) {} | https://blog.csdn.net/qq_29519041/article/details/86316290 |
方法 | private void fastRemove(int index) {} | |
方法 | public void clear() {} | |
方法 | public boolean addAll(Collection extends E> c) {} | |
方法 | public boolean addAll(int index, Collection extends E> c) {} | |
方法 | protected void removeRange(int fromIndex, int toIndex) {} | |
方法 | private void rangeCheck(int index) {} | |
方法 | private void rangeCheckForAdd(int index) {} | |
方法 | private String outOfBoundsMsg(int index) {} | |
方法 | public boolean removeAll(Collection> c) {} | |
方法 | public boolean retainAll(Collection> c) {} | |
方法 | private boolean batchRemove(Collection> c, boolean complement) {} | |
方法 | private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException{ |
|
方法 | private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {} |
|
方法 | public ListIterator |
|
方法 | public ListIterator |
|
方法 | public Iterator |
|
方法 | private class Itr implements Iterator |
|
方法 | public boolean hasNext() {} | |
方法 | public E next() {} | |
方法 | public void remove() {} | |
方法 | public void forEachRemaining(Consumer super E> consumer) {} | |
方法 | final void checkForComodification() {} | |
内部类ListItr | private class ListItr extends Itr implements ListIterator |
|
ListItr的方法 | public boolean hasPrevious() { | |
ListItr的方法 | public int nextIndex() { | |
ListItr的方法 | public int previousIndex() { | |
ListItr的方法 | public E previous() { | |
ListItr的方法 | public void set(E e) { | |
ListItr的方法 | public void add(E e) { | |
方法 | public List |
|
静态方法 | static void subListRangeCheck(int fromIndex, int toIndex, int size) { | |
1460行的代码太多了,慢慢更吧...
------------- 最后结束修改于2019年1月 10日 22:45 待续... -------------
------------- 最后结束修改于2019年1月 11日 20:46 待续... -------------