ArrayList source resolved [a]

ArrayList source resolved [a]

Welcome reproduced, reprinted, please indicate the source, thank you.

https://www.cnblogs.com/sx-wuyj/p/11177257.html

The set list at work with a collection of relatively more, and ArrayList can be said that the business end of every day, the students are using. For internal mechanism ArrayList I am also a little knowledge, so I decided to take a look at the source code. I used to go IEDA View source , a copy of the JDK source code, and then open the IDEA, find the corresponding class, set an IDEA, so you can easily add comments directly within the code. another point, do not directly to the configuration of your environment JDK directly open, to avoid in the process you look at the source code changes somewhere, affect your normal operation of the project.

1.1 ArrayList system

  • Iterable: iterable interfaces defined in the method returns an iterator, iterator corresponds to the package, while achieving iterable class interface can support for each loop;
  • Collction: root interface frame set, the following has three sub-interfaces .List Set Queue;
  • AbstractCollection: Collection implement a number of interfaces, but also defines some abstract methods to achieve sub-class.
  • List: List interface defines the interface to the public, such as toArray () size () add () and other interfaces;
  • AbstractList: AbstractList is an abstract class that implements the interface List, a branch under the root Java frame set of interface Collection

    1.2 ArrayList principle

    We look at the ArrayList constructor.
    /**
     *  有参构造  int类型  集合的大小
     */
    public ArrayList(int initialCapacity) {
        //如果参数大于0,缓冲数组的大小就为该参数
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        //如果参数等于0,创建一个空的实例数组
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            //异常为非法容量 + 参数
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }

     /**
     * Constructs an empty list with an initial capacity of ten.
     * 无参构造
     */
    public ArrayList() {
        //缓冲数组为空的默认大小的共享实例
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

     //有参构造   参数为任意类或者E的子类
    //任意类或者E的子类,孙子类等collection都可以构造一个ArrayList出来
    public ArrayList(Collection<? extends E> c) {
        //转为缓存数组
        elementData = c.toArray();
        //将数组的长度赋值给size,如果数组长度不等于0
        if ((size = elementData.length) != 0) {
            // c.toArray might (incorrectly) not return Object[] (see 6260652)
            //缓存数组的class不等于object类型数组的class
            if (elementData.getClass() != Object[].class)
                //copyOf方法:返回一个数组
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else {
            // replace with empty array.
            //替换为一个空的数组
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }

These are the constructor ArrayList, comments, write my own line by line out, which could be misunderstood, welcome criticism.

1.3 arrayList commonly used method

  • add (): Adding to the internal elements of the collection, this method is actually defined in the Collection interface, AbstractCollection abstract class implementation of this method, ArrayList override this method if you call the add method AbstractCollection directly, it will be thrown. an exception that does not support the operation. point to note is the add () a total of two, but one is boolean return value, and the other is void and has no return value.

boolean return value add (), the element is added to the last one.

    public boolean add(E e) {
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        elementData[size++] = e;
        return true;
    }

First look at ensureCapacityInternal (size + 1) This method

    private void ensureCapacityInternal(int minCapacity) {

        if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
            //max方法为一个三元运算,参数类型为int类型,(a >= b) ? a : b;
            //size+1 大于等于 初始值 返回初始值10
            minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
        }

        ensureExplicitCapacity(minCapacity);
    }
又调用了ensureExplicitCapacity()方法

    private void ensureExplicitCapacity(int minCapacity) {
            modCount++;
            //需要的大小大于底层数组的大小
            if (minCapacity - elementData.length > 0)
                grow(minCapacity);
        }
继续调用了grow()方法,这个方法很关键,先看源码

    private void grow(int minCapacity) {
        //数组长度赋值给oldCapacity
        int oldCapacity = elementData.length;
        //oldCapacity >> 1 相当于 oldCapacity / 2
        //newCapacity 为数组长度的1.5倍
        int newCapacity = oldCapacity + (oldCapacity >> 1);
        //newCapacity小于minCapacity
        if (newCapacity - minCapacity < 0)
            //minCapacity赋值于newCapacity
            newCapacity = minCapacity;
        //newCapacity大于MAX_ARRAY_SIZE
        if (newCapacity - MAX_ARRAY_SIZE > 0)
            newCapacity = hugeCapacity(minCapacity);
        //通过copyOf方法返回一个数组
        elementData = Arrays.copyOf(elementData, newCapacity);
    }

If the overall size + 1 is less than 10, 10, 10 is then minCapacity is the default size if larger than 10, then compared minCapacity size + 1.

minCapacity-lementData.length if size + 1 is smaller than the underlying array, it can continue to add elements to the array default. If the array size + 1 is greater than the bottom, it is called Grow () for expansion.

Grow () This method is a method of automatic expansion arrayList .newCapacity 1.5 times the array, is less than a first determination newCapacity
minCapacity, i.e. size + 1
is less than that assigned to the minCapacity newCapacity.

Then determines whether newCapacity greater than MAX_ARRAY_SIZE, below about MAX_ARRAY_SIZE code.

private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8;

If it is greater than the call hugeCapacity () method

    private static int hugeCapacity(int minCapacity) {
        //minCapacity 小于 0 报错
        if (minCapacity < 0) // overflow
            throw new OutOfMemoryError();
        //minCapacity大于MAX_ARRAY_SIZE吗?
        //大于返回Integer.MAX_VALUE
        //小于返回MAX_ARRAY_SIZE
        return (minCapacity > MAX_ARRAY_SIZE) ?
            Integer.MAX_VALUE :
            MAX_ARRAY_SIZE;
    }

Finally elementData, that is, the underlying array .lenth become newCapacity.
To sum up, the expansion mechanism arrayList fact modify the size of the underlying array.
Continue back to add () method to look down:

elementData[size++] = e;

This is actually very good understanding, e is the new element you want to add, size ++ is the location of a new element in the underlying array.

return true;
and finally returns a true added successfully

void add(),

    public void add(int index, E element) {
        //校验index
        rangeCheckForAdd(index);
        ensureCapacityInternal(size + 1);  // Increments modCount!!
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
        elementData[index] = element;
        size++;
    }

rangeCheckForAdd(index);

 private void rangeCheckForAdd(int index) {
     //如果index大于size或者index小于0 就抛出异常
        if (index > size || index < 0)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

ensureCapacityInternal(size + 1);

In front of this I said, not in elaborate, you can take a look in front of add () returns with the analytical values.

System.arraycopy(elementData, index, elementData, index + 1,size - index);

Call arraycopy System provided by (), which is a static native method, native not described here, can be viewed Baidu. This method is replication between the current array.

    elementData:底层数组.
    index:数组要复制的起始位置.
    elementData:复制后的数组.
    index + 1:数组放置的起始位置.
    size - index:复制的长度

elementData[index] = element;

Element to be added into the specified location.

size++

Length + 1 of the set.

Guess you like

Origin www.cnblogs.com/sx-wuyj/p/11731715.html