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

Autel MaxiIM608 Read PIN Code for Dodge Smart Key

myrocks之事务处理

XTOOL X100 Pad2 Read Peugeot 206 BSI Pin Code Test Report