Java Collection Detailed--what is List__java

Source: Internet
Author: User
Tags assert data structures int size prev
Brief

The previous chapter briefly describes what a collection is and what kinds of collections there are.
In this chapter we mainly introduce one of the implementation of collection, List.



What is List

In the previous chapter, we have learned that list is divided into 3 categories, ArrayList, linkedlist and vectors.
In order to further clarify the structure of the list, I drew a picture here, to review

Abstarctcollection in the previous Java collection-What is a collection has a simple introduction, it is the collection interface part of the implementation

1.List Interface

First look at the official definition of the list

This description solves the difference between the two questions that many companies often ask about the list and what the set is.
It is clear from the above that the list is an ordered set, unlike set, where the list allows the value of the item to be stored null, also allows storage items that store equal values, and E1.equal (E2).

The list is inherited from the collection interface and extends some of the methods that are only part of the list, except for collection common methods.

From the above figure can be found, the list than collection mainly a few add (...) ) method and remove (...) The overloads of the method, as well as a few index (...), get (...) Method.
And Abstractlist also just realize the list interface part of the method, and Abstractcollection is a train of thought, here is not specifically introduced, interested students can study under their own.

2.ArraryList

ArrayList is a list of array implementations, and because the data is stored in an array, it is also characterized by arrays of queries, but the insertion and deletion of the middle part is slow. Let's look at a few key pieces of code.

First is the ArrayList class relations and the member variables

ArrayList inherits Serializable and declares Serialversionuid, which means that ArrayList is a serializable object that can be passed in bundle by the public class arraylist<e> Extends abstractlist<e> implements List<e>, Randomaccess, cloneable, java.io.Serializable {privat

    E static final long serialversionuid = 8683452581122892189L;
     /** * Default initial capacity.

    * private static final int default_capacity = 10;
     /** * Shared Empty array instance used for empty instances.

    * * private static final object[] Empty_elementdata = {};
     /** * The array buffer into which the elements of the ArrayList are stored. * The capacity of the ArrayList is the length of this array buffer. any * empty ArrayList with elementdata = = Empty_elementdata would be expanded to * default_capacity when the Firs
     t element is added.

    //////////////From here, the ArrayList is implemented by array, and the default size of the default array is the private transient object[] elementdata; /** * The size of the ArrayList (the number of ElemeNTS it contains).
 * * @serial/private int size;

And then the constructor

ArrayList has 2 constructors, one is the default parameterless, one is the passed-in array size
/////In the Javaeffect book explicitly mentions that if you know or estimate the number of data items you want, you need to pass in the initialcapacity
// Because if you use an parameterless constructor, you first assign the Empty_elementdata to Elementdata
//And then call the Arrays.copyof () method, extending the array size, based on the number of inserts in the current array size comparison.
/cause performance Waste
/**
     * Constructs an empty list with the specified initial capacity.
     *
     * @param  initialcapacity The  initial capacity of the list
     * @throws illegalargumentexception if the SP Ecified Initial capacity
     * is negative/public
    ArrayList (int initialcapacity) {
        super ();
        if (initialcapacity < 0)
            throw new IllegalArgumentException ("illegal Capacity:" +
                                               initialcapacity);
        This.elementdata = new object[initialcapacity];
    }

    /**
     * Constructs a empty list with an initial capacity of ten.
     * * Public
    ArrayList () {
        super ();
        This.elementdata = Empty_elementdata;
    }

Then the Add () action

First of all, it is only the specified index to perform the add operation, or the add operation at the tail, will first confirm whether the current array space enough to insert data//and from//int oldcapacity = elementdata.length;
int newcapacity = oldcapacity + (oldcapacity >> 1);
if (newcapacity-mincapacity < 0)//newcapacity = mincapacity; See, ArrayList default each time is to increase the size of 50% and mincapacity compared, if still not enough, the//size expansion to mincapacity//Then, if the end of the team to insert, but also simple, the array to move backward one, and then assign the value/ 
     If it is inserted in the middle, need to use the System.arraycopy, the index start all the data backward to move one//and then insert/** * Appends the specified element to the "end of" this list. * * @param e element to is appended to this list * @return <tt>true</tt> (as specified by {@li  NK Collection#add}) */public boolean Add (E e) {ensurecapacityinternal (size + 1);
        Increments modcount!!
        elementdata[size++] = e;
    return true; }/** * Inserts the specified element at the specified position on this * list. Shifts the element currently at this position (if any) and * No subsequent elements to the right (adds one to TheiR indices).
     * * @param index which the specified element is inserted * @param element element to be inserted * @throws indexoutofboundsexception {@inheritDoc} */public void Add (int index, E element) {Rangech

        Eckforadd (index);  Ensurecapacityinternal (size + 1);
        Increments modcount!!
        System.arraycopy (Elementdata, index, Elementdata, index + 1, size-index);
        Elementdata[index] = element;
    size++;
                private void ensurecapacityinternal (int mincapacity) {if (Elementdata = = Empty_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 void Grow (int mincapacity) {//overflow-conscious code int oldcapacity = ELEMENTDATA.L
        Ength;
        int newcapacity = oldcapacity + (oldcapacity >> 1);
        if (newcapacity-mincapacity < 0) newcapacity = mincapacity;
        if (newcapacity-max_array_size > 0) newcapacity = hugecapacity (mincapacity);
    Mincapacity is usually the close to size, so this is a win:elementdata = arrays.copyof (Elementdata, newcapacity); }

Then the Remove action

Personally feel the entire remove operation of the code has been written very redundant, unlike Oracle these great God style//First look at the Remove (int index)//first boundary confirmation, whether the incoming index exceeds the current size of the array, if it throws an exception//if in the array range, To move the data after the index whole forward one, the last value empty//If the Remove (object o), incoming is an object, will do a indexof operation, go to the current array to find//judge whether exists, the code here is very redundant, is to copy the IndexOf code once, completely can call the IndexOf method//based on whether the return value is-to determine whether the value exists, if there is to call the Fastremove method//fastremove (int index) and remove (int Index) method except the boundary check is exactly the same//can be called after the Remove call Rangecheck (index) after the call to Fastremove.//This is not very clear the intent of the designer/** * Removes the element at th
     e specified position in the this list.
     * Shifts any subsequent elements to the "left" (subtracts one from their * indices).
     * * @param index The "the" is removed * @return the element that is removed from the list

        * @throws indexoutofboundsexception {@inheritDoc} */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, nummoved); Elementdata[--size] = null;
    Clear to let GC does its work return oldValue;  }/** * Removes the the specified element from this list, * if it is present.  If The list does not contain the element, it is * unchanged. More formally, removes the "element with" lowest index * <tt>i</tt> such that * <tt> (o==null &nbsp;?  &nbsp;get (i) ==null&nbsp;:&nbsp;o.equals (get (i)) </tt> * (if such a element exists).
     Returns <tt>true</tt> If this list * contained the specified element (or equivalently, if this list
     * Changed as a result of the call). * * @param o element to is removed from-list, if present * @return <tt>true</tt> if this list C  Ontained the specified element */public boolean remove (Object o) {if (o = = null) {for intindex = 0; index < size;
                    index++) if (elementdata[index] = = null) {fastremove (index);
                return true; } else {for (int index = 0; index < size; index++) if (o.equals) (Elementdata[inde
                    X])) {fastremove (index);
                return true;
    return false;
     }/* Private Remove method, skips bounds checking and does not * return the value removed.
        * * private void Fastremove (int index) {modcount++;
        int nummoved = size-index-1; if (nummoved > 0) system.arraycopy (elementdata, index+1, Elementdata, index, n
        ummoved); Elementdata[--size] = null; Clear to let GC does its work}

IndexOf

This is exactly the same as the top remove, and it's not discussed. 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 element Data[i]) return
                    i;
        }
        return-1;
    }


3.Vector

Vector is ArrayList's thread-safe version, its methods are synchronized locks, and the other implementation logic is the same.
If the thread safety requirements are not high, you can choose ArrayList, after all, synchronized is also very performance-consuming

4.LinkedList

So name thinking is linked list, and our university in the data structure of the linked list is a matter, linkedlist or a two-way linked list.

LinkedList inherits from Abstractsequentiallist, and ArrayList a routine. The internal maintenance of 3 member variables, one is the current list of the head node, one is the tail node, as well as the chain table length. And then we're looking at node this data structure.

and C-language implementation of the same way, because it is a two-way linked list, so recorded Next and Prev, but the C language in the pointer replaced by the object.

And then we're simply looking at the list limit query, insert and delete operations

The first is add (e e) operation

    Students who have studied data structures look at this part of the code is particularly easy//first look at the void Linklast (e e), the tail insert//is the newnode of the front node to perform the current tail node, newnode after the node to perform NULL, because it is in the tail Then point the rear node of the current tail node to NewNode, because now the tail node is not the last one//and then look at the middle insert//is also a routine. Suppose you now insert a newnode//in number 3rd to find the 2nd node through the current 3rd node prev, and then modify next for node 2nd, point to Nownode//Then Nownode prev to Node 2nd, next to Node 3rd//Last 3 The prev of the node is changed to Nownode,next//This completes a middle insert/** * Inserts the specified element at the specified position
     This list. * Shifts the element currently at this position (if any) and all * Subsequent elements to the right (adds one to Thei
     R indices).
     * * @param index which the specified element is inserted * @param element element to be inserted * @throws indexoutofboundsexception {@inheritDoc} */public void Add (int index, E element) {Checkpo

        Sitionindex (index);
        if (index = = size) linklast (element);
    else Linkbefore (element, node (index)); }

    /**
     * Appends the specified element to the "end of" this list.
     * * <p>this method are equivalent to {@link #addLast}. 
     * @param e element to is appended to this list * @return {@code true} (as specified by {@link Collection#add})
        * * Public boolean Add (E e) {linklast (e);
    return true;
     }/** * Links e as last element.
        * * void Linklast (e e) {final node<e> L = last;
        Final node<e> NewNode = new node<> (l, E, NULL);
        last = NewNode;
        if (L = = null), NewNode;
        else L.next = NewNode;
        size++;
    modcount++;
     }/** * Inserts element e before Non-null Node succ.
        */void Linkbefore (e E, node<e> succ) {//assert succ!= null;
        Final node<e> pred = Succ.prev;
        Final node<e> NewNode = new Node<> (pred, E, SUCC);
        Succ.prev = NewNode; if (pred = null)
            i = NewNode;
        else Pred.next = NewNode;
        size++;
    modcount++; }

Then the void Linklast (e e) Action

IndexOf operation is very simple, is to traverse the entire list from scratch, if not on the reverse-1, there will be returned the current subscript/** * Returns The index of the first occurrence of the specified eleme
     NT * In this list, or-1 if this list does not contain the element. * More formally, returns the lowest index {@code i} such that * <tt> (o==null&nbsp;?
     &nbsp;get (i) ==null&nbsp;:&nbsp;o.equals (get (i)) </tt>, * or-1 If there is no such index.
     * * @param o element to search for * @return The index of the ' the ' occurrence of the specified element in * This list, or-1 if this list does not contain the element */public int indexOf (Object o) {in
        T index = 0;
                    if (o = = null) {for (node<e> x = i x!= null; x = X.next) {if (X.item = = null)
                return index;
            index++; } else {for (node<e> x = i x!= null; x = X.next) {if (O.equals (X.item)
    )                return index;
            index++;
    }} return-1; }

Although IndexOf is very simple, I have written an example here to help you understand

List List = new ArrayList ();
        List.add ("Zero");
        List.add (null);
        List.add ("two");
        List.add (null);
        List.add ("three");

        LOG.I ("Test", "Index:" + list.indexof (null));

Can you tell the answer accurately without looking at the answer?

Answer:i/test:index:1

From this example you can see the characteristics of the three-point list
1. is to find in order
2. Allow storage entries to be empty
3. Allow the values of multiple storage items to be equal

Last look at the Remove action

    If you directly adjust the no parameter remove (), the default Delete header node//delete header node is very simple, that is, the value of the head node is emptied, next empties//then NextNode only as the head node, then empties next prev//last size minus 1 If you delete an intermediate node, call remove (int index)//first determine whether the node of index corresponds to the head node, that is, whether index is 0//If it is not an intermediate node, the prev of X points to the next public E remove of X
    () {return Removefirst ();
        Public E-Remove (int index) {checkelementindex (index);
    Return unlink (node (index));
        Public E Removefirst () {final node<e> f = i;
        if (f = = null) throw new Nosuchelementexception ();
    Return Unlinkfirst (f);
        Private E Unlinklast (node<e> l) {//assert L = = last && l!= null;
        Final E element = L.item;
        Final node<e> prev = L.prev;
        L.item = null; L.prev = null;
        Help GC last = prev;
        if (prev = null) is a = null;
        else Prev.next = null;
        size--;
        modcount++;
    return element; }

    /**
     *Unlinks non-null node x.
        */E unlink (node<e> x) {//assert x!= null;
        Final E element = X.item;
        Final node<e> next = X.next;

        Final node<e> prev = X.prev;
        if (prev = = null) {i = next;
            else {prev.next = next;
        X.prev = null;
        } if (next = null) {last = prev;
            else {next.prev = prev;
        X.next = null;
        } X.item = null;
        size--;
        modcount++;
    return element;
     }/** * Unlinks non-null-A-node F.
        * Private E Unlinkfirst (node<e> f) {//assert F = = a && f!= null;
        Final E element = F.item;
        Final node<e> next = F.next;
        F.item = null; F.next = null;
        Help GC-i = next;
        if (next = null) last = NULL;
        else Next.prev = null;
  size--;      modcount++;
    return element; }




Summary

Through the above analysis of ArrayList and LinkedList, we can understand the 3 characteristics of list
1. is to find in order
2. Allow storage entries to be empty
3. Allow the values of multiple storage items to be equal
You know it, you know it.

Then compare the LinkedList and ArrayList implementations differently, and use a different list in different scenarios.
ArrayList is implemented by array, easy to find, return the corresponding value of the array subscript, suitable for multiple lookup scenes
LinkedList is implemented by linked list, easy to insert and delete, suitable for multiple data replacement scenes

In the next chapter, we can see how the set is implemented, and what features the set has

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.