1.ArrayList underlying data structure
The data structure of ArrayList is completed in the form of array to contain data. A series of collections such as ArrayList, LinkedList, Map and set in Java are used to hold data. The first thing you need to consider is what data structure this collection uses to contain data. Secondly, consider whether the concurrency is safe and how the performance is.
1.1 an array
I’m not going to talk too much about arrays because arrays are the underlying data structure of an ArrayList
2.ArrayList source code parsing
2.1 Using the ArrayList method
// Define an ArrayList
ArrayList<String> arrayList = new ArrayList<>();
ArrayList<String> arrayList1 = new ArrayList<>(20);
// ArrayList methods to add elements
arrayList.add("CHINA");
arrayList.add("BEIJING");
arrayList.add("CHONGQING");
// ArrayList gets elements by subscript
arrayList.get(1);
// ArrayList methods to delete elements by subscript
arrayList.remove(1);
Copy the code
2.2 some thoughts before source code
The first thing you need to think about is a couple of points and it’s probably better to look inside the source code with your questions
1. Since the data structure of an ArrayList is an array, we must define the size of the array when we create an ArrayList. Why is the size of the array not defined? You can also create a specified array size like arrayList1 above, so you can forget about the definition constructor for now
2. The default ArrayList capacity. When you keep adding elements, you don’t have the possibility that the ArrayList will not fit (under limited conditions). What are the trigger conditions for each expansion?
2.3 Source Code Parsing
Things like LinkedList and ArrayList are implementing List interfaces where you pull out the common methods and you program to the interface and I’m not going to draw the implementation diagram here
ArrayList<String> arrayList = new ArrayList<>();
ArrayList<String> arrayList1 = new ArrayList<>(20);
Copy the code
ArrayList has several important parameters:
// The default length of the initialization ArrayList
private static final int DEFAULT_CAPACITY = 10;
transient Object[] elementData;
private int size;
Copy the code
Look at the constructors first
/ / no arguments
public ArrayList(a) {
// Define an empty array
this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}
// The user will enter the specified initialization length
public ArrayList(int initialCapacity) {
// Check whether the input array length is valid
/** initializes the container if it is greater than 0; initializes the empty array if it is less than 0; throws an exception */
if (initialCapacity > 0) {
this.elementData = new Object[initialCapacity];
} else if (initialCapacity == 0) {
this.elementData = EMPTY_ELEMENTDATA;
} else {
throw new IllegalArgumentException("Illegal Capacity: "+ initialCapacity); }}Copy the code
2.4 Arraylist-add source code analysis
Analysis with the constructor of empty parameters
When you’re using an array as a container in terms of performance it’s best to specify the size of the container because when you’re doing scaling it’s best to know how big your data is and make a moderate judgment
/ / generics
public boolean add(E e) {
For details on initializing the array length, see steps 1 to 3 below
ensureCapacityInternal(size + 1); // Increments modCount!!
// Assembles arrays from numbers when the container is initialized
elementData[size++] = e;
// Return true after all operations succeed
return true;
}
// The size of the first step is now 0, so minCapacity is 1
private void ensureCapacityInternal(int minCapacity) {
ensureExplicitCapacity(calculateCapacity(elementData, minCapacity));
}
// Step 2 elementData is empty minCapacity=1
private static int calculateCapacity(Object[] elementData, int minCapacity) {
// Check whether elementData is empty
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
// Return the maximum values of DEFAULT_CAPACITY and minCapacity if null
// DEFAULT_CAPACITY=10 by default
// So return 10
return Math.max(DEFAULT_CAPACITY, minCapacity);
}
// Return minCapacity if not empty
return minCapacity;
}
/ / the third step
// Now minCapacity is 10
private void ensureExplicitCapacity(int minCapacity) {
// modCount defaults to 0
modCount++;
// overflow-conscious code
// Here is the decision to expand the mechanism
// When size+1 is greater than the size of the array, expansion is triggered
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
// 1.5x expansion mechanism
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);
}
Copy the code
When size+1 is greater than the length of the array, expansion is triggered
2.5 Arraylist-get source code Analysis
// The underlying data structure of an ArrayList is an array, so the get method gets the data from the array subscript
public E get(int index) {
// Verify the validity of the index you entered just as you did with the null series
// If you enter indexx>=size, an out-of-bounds subscript exception will be raised
rangeCheck(index);
// Returns the data contents of the array with index
return elementData(index);
}
Copy the code
2.6ArrayList-remove(index) source code Analysis
// Remove the specified element by subscript
public E remove(int index) {
// Verify the validity of the index you entered just as you did with the null series
// If you enter index>=size, an out-of-bounds exception will be raised
rangeCheck(index);
modCount++;
// Get the element you want to delete
E oldValue = elementData(index);
// Calculate the length of the array to copy
int numMoved = size - index - 1;
if (numMoved > 0)
//Object SRC: original array
// int srcPos: starts at the start of the metadata
//Object dest: Target array
//int destPos: the start position of the destination array
//int length: the length of the array to copy
System.arraycopy(elementData, index+1, elementData, index,
numMoved);
elementData[--size] = null; // clear to let GC do its work
// The remove method returns the element you removed
return oldValue;
}
Copy the code
2.7ArrayList-remove(Object O) source code analysis
// Delete data based on the data content
public boolean remove(Object o) {
// Delete data to null
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true; }}else {
[a,c,d,a]) is the first element to be deleted
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
// this is the same as remove (index)
fastRemove(index);
return true; }}return false;
}
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
}
Copy the code