Analyzing Java Collection "ArrayList" from source code

Source: Internet
Author: User

ArrayList's internal implementation is actually the familiar array, it inherits the Abstractlist, implements the List,randomaccess,cloneable and serializable interface.

The Randomaccess interface is a description of the implementation class that supports fast random access, and its random access performance is very good, usually its list implementation class:

for (int i=0, n=list.size (); i < n; i++)          list.get (i);  Faster than the following loop for (Iterator I=list.iterator (); I.hasnext ();)        I.next ();
While LinkedList sequentail access fast than random access, that is, sequential accesses are better than randomly accessed. Like LinkedList, it also implements other interfaces.

public class Arraylist<e> extends abstractlist<e> implements List<e> ;, randomaccess,cloneable,java.io.serializable{/* * Default Array size * */private static final int default_capacity = 1    0;    /* * Shared empty array instance for empty instances * */private static final object[] Empty_elementdata = {}; /* Shared empty array instance for the default size instance, how large it will be to determine whether to call it or Empry_elementdata * shared empty array instance used for default sized when the element is first added Empty instances. We * Distinguish this from empty_elementdata to know what much to inflate when * first element is added * */PR    Ivate static final object[] Defaultcapacity_empty_elementdata = {}; /** * is used to store ArrayList elements of the array buffer, ArrayList capacity is the size of this buffer, * any empty arraylist exist Elementdata = = Defaultcapacity_empty_elementda     TA, * When the first element is added, its capacity is expanded to deafault_capacity.    */transient object[] elementdata;    /* * Contains the number of elements * */private int size; ...}
As with LinkedList, it inherits Modcount from Java.util.AbstractList, and their role is the same, and one thing you can see is that the default capacity of ArrayList is 10.

The difference between Empty_elementdata and Defaultcapacity_empty_elementdata is still a bit vague, here is a simple saying when the two when used, when clearly pointed out capacity = = 0 o'clock, the use of empty_ Elementdata, the remainder uses the latter. I will be able to paste out the source code may be very clear.

 public ArrayList (int initialcapacity) {if (initialcapacity > 0) {        This.elementdata = new Object[initialcapacity];        } else if (initialcapacity = = 0) {this.elementdata = Empty_elementdata;                                               } else {throw new illegalargumentexception ("Illegal capacity:" +        initialcapacity);    }} public ArrayList () {this.elementdata = Defaultcapacity_empty_elementdata;        } public ArrayList (collection<? extends e> c) {elementdata = C.toarray ();            if (size = elementdata.length)! = 0) {//C.toarray might (incorrectly) not return object[] (see 6260652) if (elementdata.getclass () = object[].class) Elementdata = arrays.copyof (elementdata, size, object[        ].class);            } else {//Replace with empty array.        This.elementdata = Empty_elementdata; }    }

We still have to look at the basic operation of ArrayList's Add,remove,set and get (limited to the length of this article, there is no way to select parameters without index)

 public void Add (int index, E element) {Rangecheckforadd (index);  Ensurecapacityinternal (size + 1);        Increments modcount!!        System.arraycopy (Elementdata, index, Elementdata, index + 1, size-index);        Elementdata[index] = element;    size++;        } public E Remove (int index) {rangecheck (index);        modcount++;        E OldValue = elementdata (index);        int nummoved = size-index-1; if (nummoved > 0) system.arraycopy (elementdata, index+1, Elementdata, index, num        Moved); Elementdata[--size] = null;    Clear to let GC does its work return oldValue;        } public E Set (int index, E element) {Rangecheck (index);        E OldValue = elementdata (index);        Elementdata[index] = element;    return oldValue;        Public E get (int index) {rangecheck (index);    Return Elementdata (index); }

It can be seen that these operations in determining whether the index is available after the direct use of index to elementdata operation, relative to LinkedList first to Node (index), more concise, more efficient.

But there are a few ways to talk about it.

<span style= "White-space:pre" ></span>//look at the method name can be guessed, to determine whether the index can be directly add Operation Rangecheckforadd (index);        Can also guess, is used to copy the array, in the source can see, a lot of use it, in fact arrays.copyof () is actually the package system.arraycopy ();        What needs to be said well is ensurecapacityinternal ();        Ensurecapacityinternal (); It is actually a series of methods used to determine the size of the ArrayList capacity. Let's take a look at the source code, to be clearer about public void ensurecapacity (int mincapacity) {int minexpand = (Elementdata! = Defaultcapac Ity_empty_elementdata)//any size if not default element table? 0//Larger than default for default empty table.                    It ' s already//supposed to is at default size.            : default_capacity;            if (Mincapacity > Minexpand) {ensureexplicitcapacity (mincapacity); }} private void ensurecapacityinternal (int mincapacity) {if (Elementdata = = Defaultcapacity_emp Ty_elementdata) {Mincapacity = Math.max (default_capacity, mincapacity);        } ensureexplicitcapacity (mincapacity);            } private void ensureexplicitcapacity (int mincapacity) {modcount++;        Overflow-conscious code if (mincapacity-elementdata.length > 0) grow (mincapacity);        }//private static final int max_array_size = integer.max_value-8; private void Grow (int mincapacity) {//overflow-conscious code int oldcapacity = Elementdata.length            ;            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 the is a win:elementdata = arrays.copyof (Elementdata, newcapacity        ); } private static int HugecapaciTy (int mincapacity) {if (mincapacity < 0)//overflow throw new OutOfMemoryError ();                    Return (Mincapacity > Max_array_size)?        Integer.MAX_VALUE:MAX_ARRAY_SIZE; }}//I think see the code is very clear, the overall judgment is sufficient, if sufficient and greater than default_capacity,//do not modify; if less than default_capacity, use the default capacity default_capacity; If it is greater than default_capacity//But the original array is not enough, re-open an array, the size is 1.5 times times the original, and copy the original value of the past
There's one more fun way to delete in bulk

Private Boolean Batchremove (Collection<?> C, Boolean complement) {final object[] Elementdata = This.elementd        Ata        int r = 0, w = 0;        Boolean modified = false;                    try {for (; R < size; r++) if (C.contains (elementdata[r]) = = complement)            elementdata[w++] = Elementdata[r];            Determine if the condition is met, then add the original array, otherwise delete} finally {//Preserve behavioral compatibility with Abstractcollection,            Even if C.contains () throws.                        if (r! = size) {system.arraycopy (Elementdata, R, Elementdata, W,                SIZE-R);            W + = Size-r; } if (w! = size) {//clear to let GC does its work for (int i = w; i < size; i+                +) elementdata[i] = null;                Modcount + = size-w;                size = W;            Modified = true;        }        }return modified; }//Note When contains throws an exception, all subsequent elements are added to the array without any selection, so bulk deletion does not guarantee that the elements in the incoming collection are all deleted
In ArrayList, calling iterator () returns an inner class Itr object. It is defined as follows:

Private class Itr implements iterator<e> {        int cursor;       Index of next element to return        int lastret =-1;//index of the last element returned;-1 if no such        int expected Modcount = Modcount;            Method        ...}
Look at its attributes and the explanations that follow, and you will know what he means. Because every time he would re-encapsulate the original array, and we randomly access the time complexity bit O (1), so when using ArrayList, there is no need to call iterator, call it will increase the cost.

In the ArrayList there is also a list,sublist, it can intercept this, specifically see the following source:

Private class Sublist extends Abstractlist<e> implements randomaccess {        private final abstractlist<e> parent;        private final int parentoffset;        private final int offset;        int size;        Sublist (abstractlist<e> parent,            int offset, int fromIndex, int toindex) {            this.parent = parent;            This.parentoffset = FromIndex;            This.offset = offset + fromIndex;            This.size = Toindex-fromindex;            This.modcount = ArrayList.this.modCount;        }        Method        ...    }    Public list<e> sublist (int fromIndex, int toindex) {        Sublistrangecheck (fromIndex, toindex, size);        return new sublist (this, 0, FromIndex, toindex);    }
Because it implements the abstractlist, it can also complete the list method.




Analyzing Java Collection "ArrayList" from source code

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.