Java Improvement (21)-----ArrayList

Source: Internet
Author: User
Tags addall serialization

I. Overview of ArrayList

ArrayList is a dynamic array that implements the list interface, 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 implementing the list interface, this class provides methods to manipulate the size of the array used internally to store the list.

Each ArrayList instance has a capacity, which refers to the size of the array used to store the list elements. The default initial capacity is 10. As the element in the ArrayList increases, its capacity will continue to grow automatically. Each time a new element is added, ArrayList checks whether the expansion operation is required, and the expansion operation brings the data back to the new array, so if we know the volume of the specific business data, we can assign an initial capacity to ArrayList when constructing the ArrayList. This reduces the problem of copying data when expanding. Of course, before you add a large number of elements, the application can also use the ensurecapacity operation to increase the capacity of the ArrayList instance, which reduces the amount of incremental redistribution.

Note that the ArrayList implementation is not synchronous . If more than one thread accesses a ArrayList instance at the same time, and at least one of the threads modifies the list from the structure, it must remain externally synchronized. So in order to ensure synchronization, the best way to do this is to prevent accidental access to the list when it is created:

        List List = Collections.synchronizedlist (new ArrayList (...));
Second, ArrayList source analysis

ArrayList we use is too many, very familiar with, so here will not introduce its use method. ArrayList is the implementation of the list interface, the bottom of the array implementation, so its operations are basically based on the operation of the logarithmic group.

2.1. Using arrays at the bottom

Private transient object[] elementdata;

Transient?? For the Java keyword, the variable modifier, if an instance variable is declared with transient, its value does not need to be maintained when the object is stored. Java's serialization provides a mechanism for persisting object instances. When persisting an object, there may be a special object data member, and we do not want to use the serialization mechanism to save it. In order to turn off serialization on a domain of a particular object, you can precede the field with the keyword transient. When an object is serialized, the value of the transient variable is not included in the serialized representation, but the non-transient variable is included.

Here object[] Elementdata, is our ArrayList container, the basic operations described below are based on the Elementdata variable to operate.

2.2. Constructor function

The ArrayList provides three constructors:

ArrayList (): default constructor that 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, arranged in the order in which they are returned by the Collection iterator.

/**     * Constructs an empty list with an initial capacity of 10     *    /Public ArrayList () {this        ];    }        /**     * Constructs an empty list with the specified initial capacity.     */Public    ArrayList (int initialcapacity) {        super ();        if (initialcapacity < 0)            throw new IllegalArgumentException ("Illegal capacity:"                    + initialcapacity);        This.elementdata = new object[initialcapacity];    }    /**     *  Constructs a list of elements that contain the specified collection, which are arranged in the order in which they are returned by the collection iterator.     *    /public ArrayList (collection<? extends e> c) {        elementdata = C.toarray ();        size = Elementdata.length;        C.toarray might (incorrectly) not return object[] (see 6260652)        if (Elementdata.getclass ()! = Object[].class) 
   elementdata = arrays.copyof (elementdata, size, object[].class);    }

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), set (int index, E Element) This five method to achieve ArrayList increase.

Add (E E): adds the specified element to the tail of this list.

Public boolean Add (E e) {    ensurecapacity (size + 1);  Increments modcount!!    elementdata[size++] = e;    return true;    }

The ensurecapacity () method here is to expand the ArrayList collection, Elementdata (size++) = e, and point the element at the end of the list to E.

Add (int index, E Element): inserts the specified element into the specified position in this list.

public void Add (int index, E Element) {        //determine if index position is correct        if (Index > Size | | Index < 0            ) throw new Indexoutof Boundsexception (            "Index:" +index+ ", Size:" +size);        Expansion detection        ensurecapacity (size+1);         /* * Copy processing (displacement) of the source array, from index + 1 to Size-index.         * The main purpose is to empty the index position for data insertion,         which moves the element that is currently at that position and all subsequent elements to the right.          */        System.arraycopy (Elementdata, index, Elementdata, index + 1,                 size-index);        Assigns a value        elementdata[index] = element in the specified position;        size++;        }

The most fundamental method in this method is the System.arraycopy () method, the fundamental goal of this method is to empty the index position for new data to insert, it is necessary to move the array data right, which is very cumbersome and time-consuming, Therefore, if the specified data collection requires a large number of insertions (intermediate insertions), LinkedList is recommended.

AddAll (collection<? extends e> c): adds all the elements in the Collection to the end of this list, in the order of the elements returned by the specified Collection iterator.

public boolean addall (collection<? extends e> c) {        //Convert collection C to array        object[] A = C.toarray ();        int numnew = a.length;        Scale-up processing with size + numnew        ensurecapacity (size + numnew);//increments Modcount        system.arraycopy (A, 0, Elementdata, size, numnew);        Size + = Numnew;        return numnew! = 0;    }

This method is nothing more than using the System.arraycopy () method to copy the data from the C collection (the first to the array) into the Elementdata array. Here is a little introduction to the next System.arraycopy (), because the method is also used extensively. The prototype of this method is: public static voidarraycopy(object src, int srcpos, object dest, int destpos, int length). Its fundamental purpose is to replicate the elements of the array. That is, copies an array from the specified source array, starting at the specified location and ending at the specified position in the destination array. Copies the source array src from the srcpos position to the dest array, with the length of the copy and the data pasted from the Destpos position of the dest.

addall (int index, COLLECTION<? extends e> c): inserts all elements from the specified Collection into this list, starting at the specified location.

public boolean addall (int index, COLLECTION<? extends e> c) {        //determine if the position is correct        if (Index > Size | | | Index < 0 )            throw new Indexoutofboundsexception ("index:" + index + ", size:"                    + size);        Convert an array of        object[] A = C.toarray ();        int numnew = a.length;        ArrayList container expansion processing        ensurecapacity (size + numnew);//increments modcount        //arraylist container array move right position        int nummoved = Size-index;        If the move position is greater than 0, move the ArrayList container's data to the right nummoved position, ensuring that the increased data increases the        if (nummoved > 0)            system.arraycopy ( Elementdata, index, elementdata, index + numnew,                    nummoved);        Add Array        system.arraycopy (A, 0, Elementdata, index, numnew);        Container capacity becomes larger        size + = numnew;           return numnew! = 0;    }

Set (int index, E Element): replaces the element at the specified position in this list with the specified element.

Public E Set (int index, E Element) {        //detects if the inserted position is out of bounds        Rangecheck (index);        E OldValue = (e) elementdata[index];        Alternative        Elementdata[index] = element;        return oldValue;    }

2.4. Delete

ArrayList provides four methods for remove (int index), remove (Object o), removerange (int fromIndex, int toindex), and RemoveAll () The deletion of the element.

Remove (int index): removes the element at the specified position in this list.

Public E Remove (int index) {        //Position Verification        rangecheck (index);        modcount++;        The element to be removed        E oldValue = (e) elementdata[index];           The number of digits shifted to the left        int nummoved = size-index-1;        If you need to move, you want to move left nummoved bit        if (nummoved > 0)            system.arraycopy (elementdata, index + 1, elementdata, index,                    nummoved);        Empty the last element        elementdata[--size] = null;//Let GC does its work        return oldValue;    }

Remove (Object o): removes the first occurrence of the specified element (if present) in this list.

public boolean remove (Object o) {        ///Because NULL is allowed in ArrayList, so null is required to determine        if (o = = null) {for            (int index = 0; ind ex < size; index++)                if (elementdata[index] = = null) {                    //remove element                    Fastremove (index) at this position;                    return true;                }        } else {for            (int index = 0; index < size; index++)                if (O.equals (Elementdata[index])) {                    fastremove (index);                    return true;                }        }        return false;    }

where the Fastremove () method removes the element from the specified position. As follows

private void Fastremove (int index) {        modcount++;        int nummoved = size-index-1;        if (nummoved > 0)            system.arraycopy (Elementdata, index+1, Elementdata, index,                             nummoved);        Elementdata[--size] = null; Let GC do it work    }

removerange (int fromIndex, int toindex): removes all elements of an index in a list between FromIndex(including) and Toindex(not included).

protected void RemoveRange (int fromIndex, int toindex) {        modcount++;        int nummoved = Size-toindex;        System                . Arraycopy (Elementdata, Toindex, Elementdata, FromIndex,                        nummoved);        Let GC does its work        int newSize = size-(toindex-fromindex);        while (size! = newSize)            elementdata[--size] = null;    }

RemoveAll (): is a method inherited from Abstractcollection, ArrayList itself does not provide the implementation.

public boolean RemoveAll (collection<?> c) {        Boolean modified = false;        Iterator<?> e = Iterator ();        while (E.hasnext ()) {            if (C.contains (E.next ())) {                e.remove ();                Modified = true;            }        }        return modified;    }

2.5. Find

ArrayList provides a get (int index) with the elements in the read ArrayList. Since ArrayList is a dynamic array, we can get the elements in ArrayList according to the subscript, and the speed is relatively fast, so ArrayList is longer than random access.

Public E get (int index) {        Rangecheck (index);        Return (E) elementdata[index];    }

2.6. Expansion

In the source code of the new method above we find that this method exists in each method: Ensurecapacity (), which is the method of ArrayList expansion. In front of the ArrayList each new element will need to conduct capacity detection, if the number of elements after the new element will exceed the capacity of ArrayList, will be expanded to meet the needs of new elements. So when we know the volume of business data or need to insert a lot of elements, I can use ensurecapacity to manually increase the capacity of the ArrayList instance to reduce the number of incremental redistribution.

public void ensurecapacity (int mincapacity) {        //modify timer        modcount++;        ArrayList capacity size        int oldcapacity = elementdata.length;         /* * If the current required length is greater than the length of the current array, the expansion operation         *        /if (Mincapacity > Oldcapacity) {            Object olddata[] = elementdata;< C9/>//calculates the new capacity size, which is 1.5 times times the current capacity            int newcapacity = (oldcapacity * 3)/2 + 1;            if (Newcapacity < mincapacity)                newcapacity = mincapacity;            Array copy, generating a new array            elementdata = arrays.copyof (Elementdata, newcapacity);        }    }

Here is a question, why each expansion processing will be 1.5 times times, instead of 2.5, 3, 4 times times? By Google find, 1.5 times times the expansion is the best multiple. Because a one-time expansion is too large (2.5 times times, for example) can waste more memory (1.5 times times the maximum waste of 33%, and 2.5 will be wasted 60%, 3.5 times times will be wasted 71% ...). However, the one-time expansion is too small, need to reallocate memory multiple times, the performance consumption is more serious. So 1.5 times times just as good, can meet performance requirements, and will not cause a lot of memory consumption.

To deal with this ensurecapacity () expansion array, ArrayList gives us the ability to resize the underlying array to the size of the actual elements saved in the current list. It can be implemented by means of the TrimToSize () method. This method minimizes the storage of ArrayList instances.

public void TrimToSize () {        modcount++;        int oldcapacity = elementdata.length;        if (Size < oldcapacity) {            elementdata = arrays.copyof (elementdata, size);        }    }

Java Improvement (21)-----ArrayList

Related Article

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.