Read Code——ArrayList
Posted 小可爱的大笨蛋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Read Code——ArrayList相关的知识,希望对你有一定的参考价值。
成长总是痛苦的,但你不得不去成长。
在日常的开发过程中,我们经常会用到一个类 List ,可以说这个类是必不可少的,完美的代替了数组,使得数组操作更加的方便,更加的友好。在其下,我们进场使用两个类对其进行实例化:ArrayList和LinkedList,其实说实话,LinkedList用到的也不是很多。
1.关于List
List本身是一个接口,继承了Collection,Collection是Java提醒中集合操作的两大阵营的其中之一(另一个是Map)。List定义了一系列的方法,像常用的add,remove,get,set。
2.关于ArrayList
从上图种不难看出,ArrayList实现了List接口,但同时继承了AbstractList,但是AbstractList又实现了List接口,值得一提的是,作者这里使用了模板设计模式,使得整个List的子类实现的过程更加的规范化。
2.1 ArrayList的初始化
当直接new一个ArrayList对象的时候,可以发现,他会之间对一个属性进行赋值。
public ArrayList()
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
elementData 这个属性其实就是一个没有初始化的数组。
/**
* The array buffer into which the elements of the ArrayList are stored.
* The capacity of the ArrayList is the length of this array buffer. Any
* empty ArrayList with elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA
* will be expanded to DEFAULT_CAPACITY when the first element is added.
*/
transient Object[] elementData; // non-private to simplify nested class access
而 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 = ;
2.2 ArrayList的添加
add方法可以说是抛开初始化之外用的最多的一个方法了
/**
* 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;
总共只有三步:
- 第一步:确保整个容器的大小;
- 第二步:将数据存入(从这里可以看出,ArrayList不是线程安全的);
- 第三步:返回数据。
接下来,我们进入到 ensureCapacityInternal去看看:
private void ensureCapacityInternal(int minCapacity)
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
计算一个容量:
private static int calculateCapacity(Object[] elementData, int minCapacity)
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA)
return Math.max(DEFAULT_CAPACITY, minCapacity);
return minCapacity;
返回最大的那个容量。
之后需要做一个容器大小的增长:
private void ensureExplicitCapacity(int minCapacity)
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
先将容器的大小自增,之后比较现在的大小和实际的大小是否存在误差,防止其溢出,即完成自动扩容。
/**
* The maximum size of array to allocate.
* Some VMs reserve some header words in an array.
* Attempts to allocate larger arrays may result in
* OutOfMemoryError: Requested array size exceeds VM limit
*/
private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;
/**
* 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 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);
从上述代码中可以发现,每次扩容的大小是原来的一半。即新的大小应该是:
new = old + old / 2 或 new = old。
以上是关于Read Code——ArrayList的主要内容,如果未能解决你的问题,请参考以下文章
完美解决蚁剑{“code“:“econnreset“,“errno“:“econnreset“,“syscall“:“read“}
Tips for newbie to read source code
Autel MaxiIM608 Read PIN Code for Dodge Smart Key