Java Basics Trap (vii)

Source: Internet
Author: User

This article is published in my blog .

Last said the next hashset and hashmap relationship between, wherein HASHMAP this internal has such a sentence:

Static final float default_load_factor = 0.75f;

This sentence represents a constant that is re-constructing an array of twice times the size of the container when the number of containers reaches 0.75%. Even if these 2 are collections, let's look at other collection classes today, such as: ArrayList, Vector, LinkedList, start.

First look at the source of the next ArrayList, these collection classes are under the Java.util package; see its construction:

    Private transient object[] elementdata;    Public ArrayList (int initialcapacity) {        super ();        if (initialcapacity < 0)            throw new IllegalArgumentException ("Illegal capacity:" + initialcapacity);        This.elementdata = new object[initialcapacity];    }    Public ArrayList () {this        ];    }

We can see that when we new ArrayList (), the essence of it is internally initialized by default to an array of object objects of length 10. Understand that the interior is implemented using arrays; Keep looking at that. What if we add it? Look at its code:

    Public boolean Add (E e) {        ensurecapacity (size + 1);  Increments modcount!!        elementdata[size++] = e;        return true;    }    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 = arrays.copyof (Elementdata, newcapacity);        }    }

As can be seen here, the Add object is the first to determine whether the position of the caret is larger than the length of the array, yes, re-instantiate an array assignment to Elementdata, re-instantiate the array when the length of the current length of *3/2 + one calculation, that is every time the add will be judged, If you insert many (hundreds of thousands of) element objects at once, then we can imagine that 10 elements will re-instantiate an array, 16 times again, at 25 time again, so the performance should be too poor, So when we know the length of the array, we can call the parameter constructs directly to improve performance such as:

ArrayList list = new ArrayList (10000);

Then let's look at its Query method:

    Public Boolean contains (Object o) {        return indexOf (o) >= 0;    }    public int indexOf (Object o) {        if (o = = null) {for            (int i = 0; i < size; i++)            if (elementdata[i]==null) 
   return i;        } else {for            (int i = 0; i < size; i++)            if (O.equals (Elementdata[i]))                return i;        }        return-1;    }

You can see that the query is traversing the entire array! To see the removal code:

    Public E Remove (int index) {        Rangecheck (index);        modcount++;        E OldValue = (e) elementdata[index];        int nummoved = size-index-1;        if (nummoved > 0)            system.arraycopy (Elementdata, index+1, Elementdata, index,nummoved);        Elementdata[--size] = null;        return oldValue;    }    private void Rangecheck (int index) {        if (index >= size)        throw new Indexoutofboundsexception ("Index:" +index + ", Size:" +size);    }

The removal of the code is also the first to determine whether the small mark is exceeded, or intercept the array. From this aspect we can see: ArrayList when looking for the direct use of the subscript traversal, increase the deletion when it is necessary to reconstruct a new array of performance consumption is relatively large!

Now look at the vector class, which looks at its structure first:

    protected object[] Elementdata;    Public Vector (Int. initialcapacity) {This        (initialcapacity, 0);    }    Public Vector () {This        (ten);    }    Public Vector (int initialcapacity, int capacityincrement) {        super ();        if (initialcapacity < 0)            throw new IllegalArgumentException ("Illegal capacity:" + initialcapacity);        This.elementdata = new Object[initialcapacity];        This.capacityincrement = capacityincrement;    }

It can be seen that this vector is also using an object array to implement, initialcapacity we can see is set the length of the array, and capacityincrement is what, we look at its comments:

    /**     * The amount by which the capacity of the vector are automatically     * incremented when its size becomes greate R than its capacity.  If     * The capacity increment is less than or equal to zero, the capacity * of the vector was doubled each time     it needs to grow.     *     * @serial * *     

My English is not good, wonderful, a little difficult we look at the use of the place:

    private void Ensurecapacityhelper (int mincapacity) {    int oldcapacity = elementdata.length;        if (Mincapacity > Oldcapacity) {            object[] olddata = elementdata;            int newcapacity = (capacityincrement > 0)? (Oldcapacity + capacityincrement): (oldcapacity * 2);            if (Newcapacity < mincapacity) {            newcapacity = mincapacity;            }            Elementdata = arrays.copyof (Elementdata, newcapacity);        }    }

As you can see from this code, when Capacityincrement>0 is set, the object is added as the length of the new array when the new array is re-constructed, otherwise it is twice times the length of the original array. Ok! Brother English is not good, bitter force Ah!

Let's look at how the additional deletions are implemented. Look at the code:

    Public synchronized Boolean Add (E e) {        modcount++;        Ensurecapacityhelper (Elementcount + 1);        elementdata[elementcount++] = e;        return true;    }    Public synchronized E Remove (int index) {        modcount++;        if (index >= elementcount)            throw new ArrayIndexOutOfBoundsException (index);        Object oldValue = Elementdata[index];        int nummoved = elementcount-index-1;        if (nummoved > 0)            system.arraycopy (Elementdata, index+1, Elementdata, Index, nummoved);        Elementdata[--elementcount] = null;        Return (E) oldValue;    }

Ah, here appears the synchronized key word, is the synchronization management Oh. Add add when the first to determine whether the need to reconstruct the new array, and then assign values, delete the first to determine whether the subscript is exceeded, or directly intercept the array, this is the same as ArrayList! It can be seen that the inside of the vector is also using an array to implement, but in addition to the deletion of some methods to use synchronization even in multi-threaded can be ensured correct. This will be slightly more performance than ArrayList, but should be used in a multithreaded environment to ensure that queries are executed correctly.

Let's take a look at LinkedList and look at the code:

public class linkedlist<e>     extends abstractsequentiallist<e>     implements List<e>, Deque <e>, Cloneable, java.io.Serializable

From this can see, this linkedlist unexpectedly realized deque Oh, can look at this note, is a two-way loop linked list. That should be linked to the list of people should know, the list in the insertion of data delete data will not be an array of fast, the reason is not to remove the data directly to modify the pointer can be, but there is a bad place is the query Ah, is to first from the current node location from the next or online to find a more time-consuming!

Public boolean Add (E e) {        Addbefore (e, header);        return true;    }    Private entry<e> Addbefore (e E, entry<e> Entry) {        entry<e> newEntry = new Entry<e> (e, Entry, E ntry.previous);        NewEntry.previous.next = NewEntry;        newEntry.next.previous = NewEntry;        size++;        modcount++;        return newEntry;    }    Private E Remove (entry<e> e) {        if (e = = header)            throw new Nosuchelementexception ();        E result = e.element;        E.previous.next = E.next;        e.next.previous = e.previous;        E.next = e.previous = null;        E.element = null;        size--;        modcount++;        return result;    }

As can be seen from the above code, the addition of the deletion is only the node of the header operation on it, which greatly improve performance.

    Private transient entry<e> Header = new entry<e> (null, NULL, NULL);    private transient int size = 0;    Public LinkedList () {        Header.next = header.previous = header;    }        private static class Entry<e> {        E element;        Entry<e> Next;        Entry<e> previous;        ......        ......    }

From this part of the code can be seen using the header to do the link node, to find a header with previous and next node, one after the entire chain table loop.

come here first this time. Keep a record of every bit of drip!


Java Basic Knowledge Trap (vii)

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.