One java.util: ArrayList

ArrayList is a linear representation of the structure of the java, java used in very high frequency, the following step by step to achieve its underlying analysis. (JDK1.8)

A constructor

ArrayList constructor takes three, are as follows,

No-argument constructor of our most frequently used, then the no-argument constructor is how to define that,

public ArrayList() {
        this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
    }

Seen from the above argument constructor without actually gives the default capacity elementData an array DEFAULTCAPACITY_EMPTY_ELEMENTDATA;

 private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};

Then there is the constructor parameters of that,

public ArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
        } else if (initialCapacity == 0) {
            this.elementData = EMPTY_ELEMENTDATA;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }

As can be seen from the above first determine whether a given initial capacity is greater than 0, greater than 0 if this value is used to generate an array of Object. If not equal to 0 and it is the same argument constructor. If less than zero exception is thrown. In the actual development it is strongly recommended to use parameterized constructor (say why below).
The last constructor is as follows,

public ArrayList(Collection<? extends E> c) {
        elementData = c.toArray();
        if ((size = elementData.length) != 0) {
            // c.toArray might (incorrectly) not return Object[] (see 6260652)
            if (elementData.getClass() != Object[].class)
                elementData = Arrays.copyOf(elementData, size, Object[].class);
        } else {
            // replace with empty array.
            this.elementData = EMPTY_ELEMENTDATA;
        }
    }

As can be seen from the above code, the set of calls class c toArray method, which returns an array elementData assigned, then judge elementData length is not 0, it is determined whether the type elementData Object, if it is not used for Object Alternatively, the unitary type into Obejct because java in the superclass of all classes are Object.
Second, the member variables

ArrayList member in the main variables and elementData size, representative of the underlying storage structure elementData ArrayList, i.e. with ArrayList array to hold the data; size refers to the (separate elementData length and area) by the number of elements in ArrayList. Other member variables like the default initial capacity of 10. ArrayList when using non-argument constructor allocates memory when using lazy loading mode, i.e. when using the new ArrayList bottom does not allocate space in real time to the discharge elements will really initialize the ArrayList array length.

Third, the common method

1、set/add

Add and set different from the method is that the method will set the return value is covered, but does not add

set(int index,E element)

Insert element at the index element, which is embodied as

public E set(int index, E element) {
        rangeCheck(index);

        E oldValue = elementData(index);
        elementData[index] = element;
        return oldValue;
    }

As can be seen from the above code, the first need to determine whether a valid index,

 private void rangeCheck(int index) {
        if (index >= size)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

That is if the index is greater than the number of elements in the ArrayList, an exception is thrown, there is a question ArrayList storage array is used, the default length is 10, then after adding an element to an ArrayList of the length of the array 10, the ArrayList the elements 1, why not let the index is greater than the size insert it.
After completion index is determined not greater than the size, the element to be inserted in the array subscript index position, the return element before.

add (E e)

E insert elements into the ArrayList type returns a boolean indicating whether the insertion is successful.

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

First make sure you can see the capacity of the array,

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;
    }

ElementData is determined whether an empty array, if the initial capacity is empty array and large size + 1, the two numbers, there should be 10 returns to the initial capacity.
The next method is

private void ensureExplicitCapacity(int minCapacity) {
        modCount++;

        // overflow-conscious code
        if (minCapacity - elementData.length > 0)
            grow(minCapacity);
    }

If the length of the array is greater than minCapacity for expansion,

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);
    }

The above code means calculates the size of the original array and adding it to the right one (1.5 times the original size) referred to as newCapacity. The expansion of the size and to compare newCapacity, whichever is larger as the capacity of the array. The original copy of elements in the array to the new array.
In retrospect add method elementData [size ++] = e; because they have an expansion of the array, it is possible to position e on the size + 1, returns true.

See below add (int index, E e)

Insert element at index e,

public void add(int index, E element) {
        rangeCheckForAdd(index);

        ensureCapacityInternal(size + 1);  // Increments modCount!!
        System.arraycopy(elementData, index, elementData, index + 1,
                         size - index);
        elementData[index] = element;
        size++;
    }

Verify the legitimacy of the index

private void rangeCheckForAdd(int index) {
        if (index > size || index < 0)
            throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
    }

And then determine the capacity of the underlying array, determining whether additional capacity is needed, if not put inserted into the index position e, where instead of using the cycle movement is inserted, but rather in portions of the copy of the array, the index before and after the element index copying the elements, and finally at the index e is inserted, is inserted in this way is faster than the cycle of movement (copy technique using the bottom).

2, get method

According to index made elements in the ArrayList,

public E get(int index) {
        rangeCheck(index);

        return elementData(index);
    }

Determining whether a given value and compare the size of the size of the index, if more than the size exception is thrown, otherwise it returns the value of its index at.
3, contains (Object o) method

O determining whether ArrayList, since the memory element array using ArrayList, so it is stored to allow duplicate values, and the method returns contains o is the position of the first occurrence.

public boolean contains(Object o) {
        return indexOf(o) >= 0;
    }
public int indexOf(Object o) {
        if (o == null) {
            for (int i = 0; i < size; i++)
                if (elementData[i]==null)
                    return i;
        } else {
            for (int i = 0; i < size; i++)
                if (o.equals(elementData[i]))
                    return i;
        }
        return -1;
    }

See ArrayList stored null value is allowed, and can keep a plurality.
O If not null, then the cycle from the beginning until the first element appears to o, which returns the subscript -1 otherwise, according to the last value of greater than 0 indexOf returns true, otherwise false.

4、remove(int index)/remove(Object o)

Remove elements from the ArrayList, you can delete according to index and elements. According to elements that were removed will be removed only to the first element of a given location, and the rest will not be deleted.

remove(int index)

public E remove(int index) {
        rangeCheck(index);

        modCount++;
        E oldValue = elementData(index);

        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // clear to let GC do its work

        return oldValue;
    }

First, delete the position is still to determine the legality. If the legal position is made to delete an index of element values (to return), because it will definitely move to delete the array, the array that is moved forward after deleting position, as used herein, it is a copy of the array.
remove (Object o)

According to delete elements, first delete the ArrayList is o elements,

public boolean remove(Object o) {
        if (o == null) {
            for (int index = 0; index < size; index++)
                if (elementData[index] == null) {
                    fastRemove(index);
                    return true;
                }
        } else {
            for (int index = 0; index < size; index++)
                if (o.equals(elementData[index])) {
                    fastRemove(index);
                    return true;
                }
        }
        return false;
    }

There is still the case null is treated individually, we do not see is null, the deletion, use size to traverse the entire array to find the equivalent of a given element in the array subscript, call the delete method in accordance with fastMove index, only the first o first occurrence of elements on the position delete that repetition will not be deleted.

private void fastRemove(int index) {
        modCount++;
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elementData, index+1, elementData, index,
                             numMoved);
        elementData[--size] = null; // clear to let GC do its work
    }

Above or delete according to index.

To be continued.

 

Guess you like

Origin www.cnblogs.com/teach/p/11494895.html