Java source code interpretation of the Util.arraylist

Source: Internet
Author: User
Tags addall array array length final int size interface reference variable
is a variable-length array implementation of the list interface. Implements all the list interface operations and allows the storage of null values. In addition to not synchronizing, ArrayList is basically equivalent to vector. Almost all methods are synchronized in the vector, but ArrayList only synchronizes WriteObject and ReadObject, others such as Add (Object), remove (int), and so on, are not synchronized.

ArrayList is a variable-length array implementation of the list interface. Implements all the list interface operations and allows the storage of null values. In addition to not synchronizing, ArrayList is basically equivalent to vector. Almost all methods are synchronized in the vector, but ArrayList only synchronizes WriteObject and ReadObject, others such as Add (Object), remove (int), and so on, are not synchronized.

1. Storage

ArrayList uses an object array to store elements.

Private transient Object elementdata[];

ArrayList implements the Java.io.Serializable interface, where the transient indicates that the attribute does not need to be serialized automatically. The following is a detailed explanation of why this is done in the WriteObject () method.

2.add and remove

Public boolean Add (Object o)
{
Ensurecapacity (size + 1);
Increments modcount!! elementdata[size++] = o;
return true;
}

Notice the Ensurecapacity () method here, which is to ensure that the length of the Elementdata array can accommodate a new element. In the "Automatic variable length mechanism" will be explained in detail.

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 does its work return oldValue;
}

The role of Rangecheck () is to conduct boundary checks. Because ArrayList uses an object array to store elements, the following elements need to be moved forward when deleting an element. When you delete an element, only the reference to the element in the Elementdata array is null, and the destruction of the specific object is handled by the garbage collector.

The role of Modcount will be described in the following "synchronization in Iterator ()".

Note: A practical method provided by system is used in the forward Move: Arraycopy (), in this case, you can see that the System.arraycopy () method can operate on the same array, which is a native method, if you are working on the same array, Will first copy from the source part to a temporary array, in the temporary array of elements copied to the target location.

3. Automatic variable length mechanism

When instantiating a ArrayList, you can specify an initial capacity. This capacity is the initial length of the elementdata array. If you use:

ArrayList list = new ArrayList ();

The default capacity is used: 10.

Public ArrayList () {this (10);}

The ArrayList provides four kinds of add () methods,

Public boolean Add (Object o)

public void Add (int index, Object Element)

public boolean AddAll (Collection c)

public boolean addall (int index, Collection c)

In each of the add () methods, a ensurecapacity (int minicapacity) method is first invoked, which guarantees that the Elementdata array is not less than minicapacity in length. The automatic variable length 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 < mincapacity) newcapacity = mincapacity;
Elementdata = new Object[newcapacity];
System.arraycopy (olddata, 0, elementdata, 0, size);
}
}

From the realization of this method can be seen ArrayList each expansion, to the original size of 1.5 times times.

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);
Increments modcount!! elementdata[size++] = o;
return true;
}

Synchronization in 4.iterator ()

A property of int is defined in the parent class Abstractlist: Modcount, which records the number of ArrayList structural changes.

protected transient int modcount = 0;

The value of Modcount is increased in all ArrayList methods involving structural changes, including: Add (), remove (), AddAll (), RemoveRange (), and Clear () methods. Each time these methods are invoked, the Modcount value is added to 1.

Note: The Modcount value of the Add () and AddAll () method is incremented in the Ensurecapacity () method that is invoked.

The iterator () method in Abstractlist (ArrayList inherits this method directly) uses a private inner member class ITR to generate a Itr object (iterator interface) to return:

Public iterator iterator () {return new Itr ();}

ITR implements the iterator () interface, which also defines an int-type property: Expectedmodcount, which is given the value of the ArrayList property of the Modcount object when the class is initialized ITR.

int expectedmodcount = Modcount;

Note: The internal member class ITR is also a member of the ArrayList class, and it can access all abstractlist properties and methods. Understanding this, the implementation of the ITR class is easy to understand.

In the Itr.hasnext () method:

public Boolean Hasnext () {return cursor!= size ();}

The size () method of the abstractlist is invoked to compare whether the current cursor position is out of bounds.

In the Itr.next () method, ITR also invokes 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 to Next;
}
catch (Indexoutofboundsexception e)
{
Checkforcomodification ();
throw new Nosuchelementexception ();
}
}

Note that the Checkforcomodification () method is called in the next () method to perform a synchronous check of the modifications:

final void Checkforcomodification ()
{
if (Modcount!= expectedmodcount) throw new Concurrentmodificationexception (); }

Now the role of Modcount and Expectedmodcount should be very clear. The operation of the elements of a collection object is not restricted while a fall operation is performed on a collection object, which includes dangerous operations such as add () or remove () that may cause a drop-down error. In Abstractlist, a simple mechanism is used to circumvent these risks. This is the role of Modcount and Expectedmodcount.

5. Serialization support

ArrayList implements the Java.io.Serializable interface, so ArrayList objects can be serialized into persistent storage media. The main attributes of the ArrayList are defined as follows:

Private static final long serialversionuid = 8683452581122892189L;

Private transient Object elementdata[];

private int size;

You can see that serialversionuid and size are automatically serialized to media, but Elementdata array objects are defined as transient. That is, all of these elements in the ArrayList are not automatically serialized into the media. Why is this done? Because the "element" stored in the Elementdata array is actually only a reference to these elements, it is not true that serializing a reference to an object is meaningless, because serialization is for deserialization, and when you deserialize it, the object's references cannot point to the original object. So here you need to manually serialize the elements of the ArrayList. This is the role of WriteObject ().

Private synchronized void WriteObject (Java.io.ObjectOutputStream s) throws Java.io.IOException
{
Write out the 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<size; i++) S.writeobject (elementdata[i));
}

So the element objects in the element array Elementdata can be correctly serialized to the storage medium.

The corresponding ReadObject () is also read from the input stream in the order of the WriteObject () method:
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.readint ();
Elementdata = new Object[arraylength];
Read in the ' all elements ' proper order.
for (int i=0; i<size; i++) Elementdata[i] = S.readobject (); }





Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.