1. ArrayList Overview
ArrayList is a dynamic array that implements the List interface. The so-called dynamic is that its size is variable. All optional list operations are implemented, and all elements including null are allowed. In addition to the List interface, this class also provides some methods to internally store the size of the List array.
Each ArrayList instance has a capacity, which is the size of the array used to store list elements. The default initial capacity is 10. As the number of elements in the ArrayList increases, the capacity of the ArrayList increases automatically. Each time a new element is added, ArrayList checks whether expansion is required. The expansion Operation Re-copies data to the new array. Therefore, if we know the specific business data volume, when constructing an ArrayList, you can specify an initial capacity for the ArrayList, which reduces the data copy issue during the expansion. Of course, before adding a large number of elements, the application can also use the ensureCapacity operation to increase the capacity of the ArrayList instance, which can reduce the number of progressive redistribution.
Note that the implementation of ArrayList is not synchronous.. If multiple threads access an ArrayList instance at the same time, and at least one thread modifies the list from the structure, it must maintain external synchronization. Therefore, to ensure synchronization, the best way is to complete the process at the time of creation to prevent accidental access to the list:
List list = Collections.synchronizedList(new ArrayList(...));
Ii. ArrayList source code analysis
We use ArrayList too much and are very familiar with it. Therefore, we will not describe how to use it here. ArrayList implements the List interface, and array is used at the underlying layer. Therefore, its operations are basically based on operations on arrays.
2.1 use arrays at the underlying layer
Object[] elementData;
Transient ?? It is a java keyword and a variable modifier. If transient is used to declare an instance variable, its value does not need to be maintained during object storage. Java serialization provides a mechanism for persistence object instances. When a persistent object is stored, there may be a special object data member. We do not want to use the serialization mechanism to save it. To disable serialization on a domain of a specific object, you can add the keyword transient before this domain. When an object is serialized, the value of the transient variable is not included in the serialized representation. However, non-transient variables are included.
Here Object [] elementData is our ArrayList container. The basic operations described below are all performed based on the elementData variable.
2.2 Constructor
ArrayList provides three constructors:
ArrayList (): default constructor, which provides an empty list with an initial capacity of 10.
ArrayList (int initialCapacity): constructs an empty list with the specified initial capacity.
ArrayList (Collection <? Extends E> c): constructs a list of elements that contain the specified collection. These elements are arranged in the order returned by the collection iterator.
(10 ArrayList( (initialCapacity < 0 IllegalArgumentException("Illegal Capacity: " +.elementData = ArrayList(Collection<? E>== (elementData.getClass() != Object[].= Arrays.copyOf(elementData, size, Object[].
2.3. New
ArrayList provides add (E e), add (int index, E element), addAll (Collection <? Extends E> c), addAll (int index, Collection <? Extends E> c) and set (int index, E element) Methods to add ArrayList.
Add (E): add the specified element to the end of the list.
+ 1); elementData[size++] =
Here, the ensureCapacity () method is to resize the ArrayList set, elementData (size ++) = e, pointing the element at the end of the list to e.
Add (int index, E element): insert the specified element into the specified position in this list.
add( (index > size || index < 0 "Index: "+index+", Size: "+ ensureCapacity(size+1+ 1- elementData[index] =++
The most fundamental method in this method is System. the basic purpose of the arraycopy () method is to leave the index position blank for new data insertion. Here, the right shift of array data is required, which is very troublesome and time-consuming, therefore, if the specified data set requires a large number of insert (intermediate insertion) operations, we recommend that you use the sort list.
AddAll (Collection <? Extends E> c): Adds all elements in the collection to the end of the list according to the sequence returned by the iterator of the specified collection.
addAll(Collection<? E> Object[] a = numNew = ensureCapacity(size + numNew); System.arraycopy(a, 0+= numNew != 0
This method simply copies the data in the C set (first quasi-converted to an array) to the elementData Array Using the System. arraycopy () method. Here we will introduce System. arraycopy () in a little bit, because this method will be used in a lot below. The prototype of this method is public static void.Arraycopy(Object src, int srcPos, Object dest, int destPos, int length ). Its fundamental purpose is to copy array elements. That is to say, copying an array from the specified source array starts from the specified position and ends at the specified position of the target array. Copy the source array src from the srcPos position to the dest array. The copy length is length, and the data is pasted from the destPos position of the dest.
AddAll (int index, Collection <? Extends E> c): inserts all elements in the specified collection into the list starting from the specified position.
addAll( index, Collection<? E> (index > size || index < 0 IndexOutOfBoundsException("Index: " + index + ", Size: " + Object[] a = numNew = ensureCapacity(size + numNew); numMoved = size - (numMoved > 0+ System.arraycopy(a, 0 size += numNew != 0
Set (int index, E element): replace the specified element in the specified position in this list.
E set(= elementData[index] =
2.4 Delete
ArrayList provides four methods to delete elements: remove (int index), remove (Object o), removeRange (int fromIndex, int toIndex), and removeAll.
Remove (int index): removes the elements at the specified position in this list.
E remove(++ E oldValue = numMoved = size - index - 1 (numMoved > 0+ 1 elementData[--size] = ;
Remove (Object o): removes the specified element that appears for the first time in this list (if any ).
(o == ( index = 0; index < size; index++ (elementData[index] == ( index = 0; index < size; index++
The fastRemove () method is used to remove elements at the specified position. As follows:
fastRemove(++ numMoved = size - index - 1 (numMoved > 0+1--size] = ; }
RemoveRange (int fromIndex, int toIndex): remove the index from the listFromIndex(Including) andToIndexAll elements between (not included.
removeRange( fromIndex, ++ numMoved = size - newSize = size - (toIndex - (size !=--size] =
RemoveAll (): the method that inherits from AbstractCollection. ArrayList itself does not provide implementation.
removeAll(Collection<?> modified = <?> e ==
2.5 search
ArrayList provides get (int index) for reading elements in ArrayList. Because ArrayList is a dynamic array, we can obtain the elements in ArrayList Based on the subscript, and the speed is relatively fast. Therefore, ArrayList is longer than random access.
E get(
2.6. Resizing
In the source code of the new method above, we found that this method exists in each method: ensureCapacity (), which is the expansion method of ArrayList. We mentioned earlier that ArrayList requires capacity detection and determination when adding new elements each time. If the number of elements after adding new elements exceeds the size of ArrayList, the scale-up operation is performed to meet the requirements of new elements. So before we know the business data volume or need to insert a large number of elements, we can use ensureCapacity to manually increase the capacity of the ArrayList instance to reduce the number of incremental redistribution.
ensureCapacity( modCount++ oldCapacity = (minCapacity >= newCapacity = (oldCapacity * 3) / 2 + 1 (newCapacity <= elementData =
Here is a question: why is each expansion process 1.5 times, instead of 2.5, 3, or 4 times? By searching through google, we found that the expansion by 1.5 times is the best multiple. Because one-time resizing is too large (for example, 2.5 times), it may waste more memory (1.5 times at most, and 33% is wasted at most, 3.5 times will waste 71% ......). However, the one-time resizing is too small, and the memory needs to be re-allocated to the array multiple times, causing serious performance consumption. So 1.5 times better, not only can meet performance requirements, but also will not cause a large amount of memory consumption.
In addition to the expansion array of ensureCapacity (), ArrayList also provides the function to adjust the capacity of the underlying array to the actual size of the elements saved in the current list. It can be implemented through the trimToSize () method. This method can minimize the storage capacity of the ArrayList instance.
++ oldCapacity = (size <=
Follow my new site:CMSBLOGS.com