Java 2 Source Code Interpretation: Java.util.ArrayList

xiaoxiao2021-03-06  64

Related source code download:

Java.util.ArrayList

Java.util.AbstractList

Java.util.list

ArrayList 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); // Incremen Modcount !! ElementData [Size ] = O; Return True;

Note that the EnSureCapacity () method here, its role is to ensure that the length of the ElementData array can accommodate 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 returna}

The role of RangeCheck () is to perform border checks. 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 ();

Use 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

From this method implementation, it can be seen that ArrayList is expanded to 1.5 times that of the original size. The implementation of each ADD () method is similar, and the implementation of the Add (Object) method is given below:

Public Boolean Add (Object O) {ENSURECAPACITY (SIZE 1); // Incremen Modcount !! ElementData [Size ] = O; Return True;

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;

In all methods of ArrayList involve structural changes, the value of modcount is increased, 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 ();

The ITR implements the Iterator () interface, which also defines an INT type attribute: ExpectedModCount, which is given the value of the Modcount property of the ArrayList object when ITR class is initialized.

INT EXPECTEDMODCOUNT = MODCOUNT;

Note: Internal membership 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 company! = Size ();}

The Size () method of the AbstractList is called, and the current cursor position is the crosstalk. In the ITr.next () method, the ITR also calls the Get (int) method defined in the AbstractList, returning the elements 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 checkforcomodification () method is called in the next () method, and the synchronization check for the modification is performed:

Final Void CheckForcomodification () {if (MODCOUNT! = ExpectedModCount) throw new control ();

The role of Modcount and ExpectedModCount is now 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 serialversionuid = 8683452581122892189l; private tar ibject 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

private synchronized void readObject (java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException {// Read in size, and any hidden stuff s.defaultReadObject (); // Read in array length and allocate array int arrayLength = s .readData = new object [arraylength]; // read in all Elements in the project or (int i = 0; i

转载请注明原文地址:https://www.9cbs.com/read-84645.html

New Post(0)