Source code interpretation of ArrayList

Properties of class public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess...

Properties of class

public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { // Version No private static final long serialVersionUID = 8683452581122892189L; // Default capacity private static final int DEFAULT_CAPACITY = 10; // Empty object array private static final Object[] EMPTY_ELEMENTDATA = {}; // Default empty object array private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {}; // Element array transient Object[] elementData; // Actual element size, default is 0 private int size; // Maximum array capacity private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; }

Constructor

ArrayList(int) constructor

public ArrayList(int initialCapacity) { if (initialCapacity > 0) { // Initial capacity greater than 0 this.elementData = new Object[initialCapacity]; // Initialize element array } else if (initialCapacity == 0) { // Initial capacity is 0 this.elementData = EMPTY_ELEMENTDATA; // Is an empty array of objects } else { // If the initial capacity is less than 0, an exception is thrown throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); } }

ArrayList() type constructor

public ArrayList() { // No parameter constructor, set element array to null this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA; }

Constructor of type ArrayList (collection <? Extends E >)

public ArrayList(Collection<? extends E> c) { // Set parameter constructor elementData = c.toArray(); // Convert to array if ((size = elementData.length) != 0) { // Parameter is a non empty set if (elementData.getClass() != Object[].class) // Whether to convert to an Object type array successfully elementData = Arrays.copyOf(elementData, size, Object[].class); // Copy if it is not an Object array } else { // Set element array to null if set size is null this.elementData = EMPTY_ELEMENTDATA; } }

curd

Add (e e e) function

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

Ensurcapacityinternal function

private void ensureCapacityInternal(int minCapacity) { if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { // Determine whether the element array is an empty array minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity); // Take the larger value } ensureExplicitCapacity(minCapacity); }

The ensureExplicitCapacity function is as follows:

private void ensureExplicitCapacity(int minCapacity) { // Modification record plus 1 modCount++; if (minCapacity - elementData.length > 0) grow(minCapacity); }

The grow function is as follows:

private void grow(int minCapacity) { int oldCapacity = elementData.length; // Old capacity int newCapacity = oldCapacity + (oldCapacity >> 1); // New capacity is 1.5 times the old capacity if (newCapacity - minCapacity < 0) // If the new capacity is less than the capacity specified by the parameter, modify the new capacity and handle the situation of 0-10 newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) // New capacity greater than maximum capacity newCapacity = hugeCapacity(minCapacity); // Specify new capacity // Copy expansion elementData = Arrays.copyOf(elementData, newCapacity); }

The hugeCapacity function is as follows:

private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow throw new OutOfMemoryError(); //MAX_ARRAY_SIZE = Integer.MAX_VALUE-8 return (minCapacity > MAX_ARRAY_SIZE) ? Integer.MAX_VALUE : MAX_ARRAY_SIZE; }

add(int index,E element) function:

public void add(int index, E element) { rangeCheckForAdd(index); ensureCapacityInternal(size + 1); //Underlying native method call System.arraycopy(elementData, index, elementData, index + 1, size - index); elementData[index] = element; size++; }

set function

public E set(int index, E element) { // Check whether the index is legal rangeCheck(index); // Save old values E oldValue = elementData(index); // Assign new value elementData[index] = element; // Return old value return oldValue; }

indexOf function

// Find whether the specified element exists in the array from the beginning public int indexOf(Object o) { if (o == null) { // Found element is empty for (int i = 0; i < size; i++) // Traverse the array to find the first empty element and return the subscript if (elementData[i]==null) return i; } else { // Found element is not empty for (int i = 0; i < size; i++) // Traverse the array, find the first element equal to the specified element, and return the subscript if (o.equals(elementData[i])) return i; } // Not found, return empty return -1; }

The above analysis shows that null is allowed in the ArrayList collection

get function

public E get(int index) { // Check whether the index is legal rangeCheck(index); return elementData(index); }

remove function

public E remove(int index) { // Check whether the index is legal rangeCheck(index); modCount++; E oldValue = elementData(index); // Number of elements to move int numMoved = size - index - 1; if (numMoved > 0) System.arraycopy(elementData, index+1, elementData, index, numMoved); // The value is null, which is good for GC elementData[--size] = null; // Return old value return oldValue; }

Comparison of Arrays.copyOf and System.arraycopy

1.System.arraycopy

src - Source array. srcPos - The starting position in the source array. dest number- Target array. destPos - The starting position in the target data. length - The number of group elements to copy. public static native void arraycopy(Object src, int srcPos, Object dest, int destPos, int length);

Usage: used in add(int index,E e) and remove(int index) functions of ArrayList
Features: new and old arrays are available, just move

2.Arrays.copyOf

original - Array to copy newLength - Length of replica to return newType - Type of replica to return public static <T,U> T[] copyOf(U[] original, int newLength, Class<? extends T[]> newType) { T[] copy = ((Object)newType == (Object)Object[].class) ? (T[]) new Object[newLength] : (T[]) Array.newInstance(newType.getComponentType(), newLength); //Math.min(original.length, newLength) to prevent overstepping System.arraycopy(original, 0, copy, 0, Math.min(original.length, newLength)); return copy; } //There are many ways to overload public static short[] copyOf(short[] original, int newLength) {...}Wait

Usage: used when expanding ArrayList, and when instantiating ArrayList through the constructor ArrayList (collection <? Extends E > C).
Features: need to create a new array, according to the newType to determine the array type.

The difference is: System.arraycopy is a part of Array.copyOf. When the target array is not created, the latter must be used. If the original array and the target array already exist, use the former by yourself

4 May 2020, 10:03 | Views: 10073

Add new comment

For adding a comment, please log in
or create account

0 comments