Related source code download: java.util.Arraylistjava.util.Abstractlistjava.util.listarrayList is a variable long array implementation of the List interface. Implement all LIST interfaces and allow storage NULL values. In addition to not being synchronized, ArrayList is basically equivalent to Vector. Almost all methods are almost synchronized in the Vector, but ArrayList is only synchronized with WriteObject and ReadObject, such as add (object), remove (int), etc. is not synchronized.
Storage
ArrayList uses an Object's array storage element. Private Transient Object ElementData []; ArrayList implements the java.io.Serializable interface, this property does not require automatic serialization. The following will explain this in the WriteObject () method.
2.Add and Remove
Public Boolean Add (Object O) {ENSURECAPACITY (SIZE 1); // increments Modcount !! ElementData [Size ] = O; Return True; Acute a new element. Take a detailed explanation in the "Automatic Aspect Mechanism". public Object remove (int index) {RangeCheck (index); modCount ; Object oldValue = elementData [index]; int numMoved = size - index - 1; if (numMoved> 0) System.arraycopy (elementData, index 1, elementData, Index, Nummoved; ElementData [- size] = null; // let gc do its work return}} RangeCheck () The role is to perform border check. Since ArrayList uses an object array storage element, you need to move the back element before deleting an element. When deleting an element, it is only set to NULL in the ElementData array, and the specific object is destroyed by the garbage collector. The role of Modcount will be described in the "synchronization" of iTerator (). Note: A practical method provided by SYSTEM: arraycopy (), in this case, can see the SYSTEM.ARRAYCOPY () method can operate the same array, this method is a native method, if When an array operates, copy the source part to a temporary array, copy the element of the temporary array to the target location.
3. Automatic growth mechanism
When instanting an ArrayList, you can specify an initial capacity. This capacity is the initial length of the ElementData array. If you use: ArrayList List = New ArrayList (); uses the default capacity: 10. Public arraylist () {this (10);} ArrayList provides four add () methods,
Public Boolean Add (Object O) Public Void Add (INDEX, OBJECT Element) Public Boolean Addall (INDEX, Collection C) In each add () method, first call a ENSURECAPACITY (int minicapacity) method, this method guarantees that the length of the ElementData array is not less than MiniCapacity. The automatic growth mechanism of ArrayList is implemented in this method. public void ensureCapacity (int minCapacity) {modCount ; int oldCapacity = elementData.length; if (minCapacity> oldCapacity) {Object oldData [] = elementData; int newCapacity = (oldCapacity * 3) / 2 1; if (newCapacity 4. Synchronization initerator () Define an INT type attribute in the parent class AbstractList: Modcount records the number of ArrayList structural changes. Protected Transient Int MODCOUNT = 0; all modcount values are added in all methods involving structural changes in ArrayList, including: add (), remove (), addall (), removerAnge (), and clear () method. Each of these methods is called once, and the value of Modcount is added 1. Note: The value of the modcount of the add () and addall () methods is incremented in the EnSureCapacity () method called. The item () method (ArrayList directly inherits this method) in AbstractList uses a private internal member class ITR to generate an ITR object (Iterator interface) Returns: public iterator itrator () {return new itr ();} ITR implementation The Iterator () interface, which defines an int type property: ExpectedModCount, which is given the value of the Modcount property of the ArrayList object when ITR class is initialized. INT EXPECTEDMODCOUNT = MODCOUNT; Note: Internal member class ITR is also a member of the ArrayList class, which can access all AbstractList properties and methods. Understand this, the implementation of the ITR class is easily understood. In the itr.hasnext () method: public boolean hasnext () {return curSor! = Size ();} Calls the Size () method of the AbstractList, which is more than the current cursor position. In the ITr.next () method, ITR also calls the Get (int) method defined in AbstractList, returning the element at the current cursor: public object next () {Try {Object Next = Get (CURSOR); checkforcomodification () ; lastRet = cursor ; return next;} catch (IndexOutOfBoundsException e) {checkForComodification (); throw new NoSuchElementException ();}} Note that the call checkForComodification () method next () method, the synchronization checking changes: final Void CheckforComodification () {if (MODCOUNT! = EXPECTEDMODMODCOUNT) throw new concurrentModificationException ();} Now that the role of Modcount and ExpectedModCount should be very clear. While falling in a collection object, it is not limited to operation of the elements of the collection object, including some hazardous operations such as add () or remove () that may cause a drop-down error. In AbstractList, a simple mechanism is used to avoid these risks. This is the role of Modcount and ExpectedModCount. 5. Serialized support ArrayList implements the java.io.serializable interface, so the ArrayList object can serialize in the persistent storage medium. The main attributes of ArrayList are defined as follows: private static final long serialversion = 8683452581122892189l; private transient object elementdata []; private Int size; It can be seen that both SerialVersionUID and SIZE will automatically serialize into the media, but the ElementData array object is defined as transient. That is to say, all of these elements in ArrayList are automatically serialized into the medium. Why do you implement this? Because the "element" stored in the ElementData is actually only a reference to these elements, it is not true object, and the serialization of an object is meaningless, because serialization is in deserialization, when you degrade sequence The reference to these objects is not possible to point to the original object. Therefore, you need to manually serialize the elements of arraylist here. This is the role of WRITEOBJECT (). private synchronized void writeObject (java.io.ObjectOutputStream s) throws java.io.IOException {// Write out element count, and any hidden stuff s.defaultWriteObject (); // Write out array length s.writeInt (elementData.length) // Write out All Elements in The Proper ORDER. FOR (INT i = 0; i