List is the implementation class of collection interface
List:
Features: orderly, repeatable
It has two commonly used implementation classes:
One. ArrayList:
Features: Storage in the form of arrays, so random access speed is faster, all of which are suitable for queries.
Disadvantage: Not suitable for insertion and deletion operations because each operation requires moving elements in the array.
According to the source code, we can draw the following points:
1.ArrayList will have a default length of 10 if we don't specify the length at initialization time.
private static final int DEFAULT_CAPACITY = 10;
2. If we exceed the original capacity when adding new elements, what does ArrayList do?
This involves the expansion mechanism of ArrayList. Since ArrayList is stored in the form of arrays, it must inherit the characteristics of arrays. Once it is declared unchangeable, how can java solve this problem?
transient Object[] elementData;
The opening statement is that a temporary variable array is ready for future array expansion.
public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; }
The ensureCapacity Internal (size + 1) of the code above is the beginning of the expansion.
Let's click in the source code and go deeper.
private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); } private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); }
Seeing this, we found that ensureExplicitCapacity was invoked in ensureCapacityInternal, and we went further.
private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};//Default empty collectionprivate static final int DEFAULT_CAPACITY = 10;//Default 10
private static int calculateCapacity(Object[] elementData, int minCapacity) {
//If the current elemenrData (current data) is an empty collection, get the capacity for the next expansion if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) { return Math.max(DEFAULT_CAPACITY, minCapacity); } return minCapacity; }
Then we go back to the next level.
private void ensureExplicitCapacity(int minCapacity) { modCount++; //Number of times a collection is modified(AbstractList.class Value in)// overflow-conscious code Detecting spillovers
//If the minimum required capacity is greater than the array len gt h, it needs to be expanded
if (minCapacity - elementData.length > 0) grow(minCapacity); }
private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); //The initial capacity is 1.5 times (1.8, 1.7) (1.6 is 1.5 times + 1) if (newCapacity - minCapacity < 0) newCapacity = minCapacity; //Assign the required values if they are still insufficient if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); //Judging large capacity, here's the code // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); //That's why storage in array form can also be expanded. } private static int hugeCapacity(int minCapacity) { if (minCapacity < 0) // overflow out of memory throw new OutOfMemoryError(); return (minCapacity > MAX_ARRAY_SIZE) ? //Ternary operation Integer.MAX_VALUE : MAX_ARRAY_SIZE; }
After reading the above code, we can conclude that if we don't give the initial value, the default value is 10, the expansion time is not to make changes on the original array, but to copy an array by 1.5 times growth.
3.ArrayList is thread insecure. To achieve thread security, you can use the synchronized keyword or Collections. synchronized List () method as follows:
List<Object> objects = Collections.synchronizedList(new ArrayList<>());