Java Collection Class (ii) Arraylist__java of list

Source: Internet
Author: User
Tags concurrentmodificationexception
ArrayList Overview:

ArrayList is an array based implementation of the list interface. It allows all elements, including NULL, to be included. Each ArrayList instance has a capacity that represents how much of the element can be stored. Each ArrayList instance has an initial size, and of course you can specify the initial size by constructing the method. As you add elements to the ArrayList, the capacity increases automatically. When the number of elements reaches the current capacity maximum, it causes the data to be copied to the new array, so if you can predict the amount of data, you can specify its capacity when constructing ArrayList. Before adding a large number of elements, the application can also use the Ensurecapacity action to increase the capacity of the ArrayList instance, which reduces the number of incremental redistribution. However, it should be noted that the implementation of this method is not synchronized. 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 maintain an external synchronization. Bottom 1 initial capacity

private static final int default_capacity = 10;
2 underlying storage
/**
 *object Type array
 *
/transient object[] elementdata;
3 Construction methods
/**
 * Specify initial capacity */public
 ArrayList (int initialcapacity) {
        if (initialcapacity > 0) {
            This.elementdata = new object[initialcapacity];
        } else if (initialcapacity = = 0) {
            this.elementdata = empty_elementdata;
        } else {
            throw new Illegalargumentexce Ption ("Illegal Capacity:" +                                   initialcapacity);
        }

   /**
    * Default construction, initial capacity of ten
    *
    /Public ArrayList () {
        this.elementdata = Defaultcapacity_empty_elementdata ;
    }

  /**
   * Initializes a ArrayList/public ArrayList using a collection
    (collection< extends e> c) {
        Elementdata = C.toarray ();
        if (size = elementdata.length)!= 0) {
            if (Elementdata.getclass ()!= object[].class)
                elementdata = arrays.copy Of (Elementdata, size, object[].class);
        else {
            this.elementdata = empty_elementdata;
        }
    }
4 Storage
ArrayList provides the set (int index, e Element), add (E), add (int index, e element), AddAll (Collection
Sets the value of the specified position element (which is understood to be an update operation)
set (int index, E Element)
Add an element to the collection, or enlarge
Add (e E) if insufficient capacity
Inserts an element into the specified position and expands if the capacity is insufficient. The original index and subsequent elements are moved one
add (int index, E Element)
5 Delete
Deletes the element at the specified position, and the elements after the index are moved forward by a public
E-Remove (int index);
Removes the first occurrence of the specified element (if present) in this list, which requires traversing the array public
boolean remove (Object o) {
The above introduction of the ArrayList of additions and deletions, and other operations, the following to see the source code

Careful observation, we'll find that there are two empty arrays.

    private static final object[] Empty_elementdata = {};

    private static final object[] Defaultcapacity_empty_elementdata = {};

What's the use of these two empty arrays? Let's take a look at the two construction methods above:

   Public ArrayList () {
        this.elementdata = defaultcapacity_empty_elementdata;
    }

    Public ArrayList (int initialcapacity) {
        if (initialcapacity > 0) {
            this.elementdata = new object[ Initialcapacity];
        } else if (initialcapacity = = 0) {
            this.elementdata = empty_elementdata;
        } else {
            throw new Illegalargumentexce Ption ("Illegal Capacity:" +
                                               initialcapacity);
        }
    

We can see that when using the default construction method, the defaultcapacity_empty_elementdata is directly assigned to Elementdata, When constructing ArrayList with a specified capacity, if initialcapacity=0, the empty_elementdata is assigned to Elementdata, The ArrayList initial capacity constructed in both of these ways is 0, so why use two different empty arrays? Want to know the answer let's take a look at Add (e e); Method:

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

From the above code can be seen in the add an element, the capacity of the operation, why the expansion of the operation here. is to prevent you from new an array, but not, resulting in a waste of space resources. Back to the question above, let's look at the ensurecapacityinternal method:

    private void ensurecapacityinternal (int mincapacity) {
        if (Elementdata = = Defaultcapacity_empty_elementdata) {
            mincapacity = Math.max (default_capacity, mincapacity);
        }
        Ensureexplicitcapacity (mincapacity);
    }

Look here there is an if judgment, when elementdata = = Defaultcapacity_empty_elementdata , there is an assignment operation on the capacity, mincapacity for Default_ Maximum value for capacity and mincapacity. Obviously when the first add element is mincapacity==1, the initial capacity is default_capacity, which is 10. So the reason to use two different empty arrays is to ensure that the initial capacity is 10 when we construct the ArrayList using the default construction method.

Now let's look at the ensureexplicitcapacity and grow methods:

    private void ensureexplicitcapacity (int mincapacity) {
        modcount++;
        Grow operation if the minimum required capacity is greater than the current array capacity
        if (mincapacity-elementdata.length > 0)
            grow (mincapacity);
    }

    private void Grow (int mincapacity) {
        int oldcapacity = elementdata.length;
        First try the new capacity for the old smelting of 1.5 times times
        int newcapacity = oldcapacity + (oldcapacity >> 1);
        if (newcapacity-mincapacity < 0)
            newcapacity = mincapacity;
        if (newcapacity-max_array_size > 0)
            newcapacity = hugecapacity (mincapacity);
        Elementdata = arrays.copyof (Elementdata, newcapacity);
    }

As you can see, the grow operation occurs when the minimum required capacity is greater than the current array capacity. First try 1.5 times times the new capacity for the old smelting, if not enough, then use mincapacity as the current expansion capacity.

In addition, there is no notice of the ensureexplicitcapacity method has a modcount++ operation, this Modcount is what to use.
  
The Modcount of ArrayList is the field inherited from the class Java.util.AbstractList:

protected transient int Modcount

This field represents the number of times that the list has been modified from the structure. Structural modification means changing the size of the list (that is, the number of elements has changed), or disrupting the list, causing an ongoing iteration to produce an incorrect result.
This field is implemented using the iterator and list iterator returned by the iterator and Listiterator methods. If you accidentally change the value in this field, the iterator (or list iterator) throws a concurrentmodificationexception to respond to the next, remove, previous, set, or add operation. When faced with concurrent modifications during an iteration, it provides fast failure behavior rather than nondeterministic behavior.

You can test the following procedure:

    public static void Main (string[] args) {
        list<integer> List = new arraylist<> ();
        List.add (ten);
        Iterator<integer> iterator = List.iterator ();
        while (Iterator.hasnext ()) {
            integer integer = Iterator.next ();
            if (integer = =)
                list.remove (integer);  Notice this place, where the result is the same as List.add (integer)}
    

The above code throws the following exception:

Exception in thread ' main ' java.util.ConcurrentModificationException at
    java.util.arraylist$ Itr.checkforcomodification (arraylist.java:901) at
    java.util.arraylist$itr.next (arraylist.java:851)
    at Main.main (Main.java:12)

Why do you report this mistake? Look at ArrayList 's iterator source code (some of which are not posted):

    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 expectedmodcount = Modcount;
        public Boolean Hasnext () {return cursor!= size;
            @SuppressWarnings ("unchecked") public E Next () {checkforcomodification ();
            int i = cursor;
            if (i >= size) throw new nosuchelementexception ();
            object[] Elementdata = ArrayList.this.elementData;
            if (i >= elementdata.length) throw new Concurrentmodificationexception ();
            cursor = i + 1;
        Return (E) Elementdata[lastret = i];
            public void Remove () {if (Lastret < 0) throw new IllegalStateException ();

            Checkforcomodification ();
try {ArrayList.this.remove (Lastret);                cursor = Lastret;
                Lastret =-1;
            Expectedmodcount = Modcount;
            The catch (Indexoutofboundsexception ex) {throw new concurrentmodificationexception (); } final void Checkforcomodification () {if (modcount!= expectedmodcount) t
        Hrow new Concurrentmodificationexception (); }
    }

We can see that as next (), remove () operations, we have to checkforcomodification () and this method does is to determine whether Modcount and Expectedmodcount are equal. An error is not equal.

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.