The use and performance analysis of JAVA LinkedList and ArrayList _java

Source: Internet
Author: User
Tags serialization

1th Part List Summary
The frame chart of the list





The List is an interface that inherits from the collection interface. It represents an orderly queue.


Abstractlist is an abstract class that inherits from Abstractcollection. Abstractlist implements functions other than size (), get (int location) in the list interface.


Abstractsequentiallist is an abstract class that inherits from Abstractlist. Abstractsequentiallist implements "all the functions of the list, which manipulate the list according to the index value."


ArrayList, LinkedList, Vector, Stack is the list of 4 implementation classes.


ArrayList is an array queue, which is the equivalent of a dynamic array. It is implemented by array, with high random access efficiency, low random insertion and random deletion.


LinkedList is a two-way linked list. It can also be manipulated as a stack, a queue, or a two-terminal queue. LinkedList random access efficiency is low, but the efficiency of random insertion and random deletion is low.


Vectors are vector queues, and like ArrayList, it is also a dynamic array, implemented by arrays. But ArrayList is not thread-safe, and vector is thread-safe.


Stack is a stack, and it inherits from vectors. Its characteristics are: Advanced and Out (FILO).



2nd Part List Usage scenario
The ultimate goal of learning something is to be able to understand and use it. The following is a summary of the use of each list of scenarios, and then analyze the reasons behind.


If it involves "stack", "queue", "linked list" and other operations, should consider using list, the specific choice of which list, according to the following criteria to choose.


(01) for the need to quickly insert, delete elements, you should use LinkedList.


(02) for fast random access elements, you should use ArrayList.


(03)


For a single-threaded environment or multithreaded environment, but the list will only be manipulated by a single thread, you should use a class that is not synchronized, such as ArrayList.


For a multithreaded environment, and the list may be manipulated by multiple threads at the same time, you should use a synchronized class such as vector.

We verify the above (01) and (02) conclusions through the following test procedures. The reference code is as follows:

Copy Code code as follows:



Import java.util.*;


Import Java.lang.Class;


/*


* @desc contrast ArrayList and linkedlist insertion, random read efficiency, deletion efficiency


*


* @author Skywang


*/


public class Listcomparetest {


private static final int COUNT = 100000;


private static LinkedList LinkedList = new LinkedList ();


private static ArrayList ArrayList = new ArrayList ();


private static vector vector = new vector ();


private static Stack stack = new stack ();


public static void Main (string[] args) {


Line feed


System.out.println ();


Insert


Insertbyposition (stack);


Insertbyposition (vector);


Insertbyposition (LinkedList);


Insertbyposition (arrayList);


Line feed


System.out.println ();


Random Reads


Readbyposition (stack);


Readbyposition (vector);


Readbyposition (LinkedList);


Readbyposition (arrayList);


Line feed


System.out.println ();


Delete


Deletebyposition (stack);


Deletebyposition (vector);


Deletebyposition (LinkedList);


Deletebyposition (arrayList);


}


Get the name of the list


private static String Getlistname (List list) {


if (list instanceof LinkedList) {


return "LinkedList";


else if (list instanceof ArrayList) {


return "ArrayList";


else if (list instanceof Stack) {


return "Stack";


else if (list instanceof Vector) {


return "Vector";


} else {


return "List";


}


}


Inserts the count element into the list at the specified location and counts the time


private static void Insertbyposition (List list) {


Long starttime = System.currenttimemillis ();


Insert count number to position 0 to the list


for (int i=0; i<count; i++)


List.add (0, I);


Long endtime = System.currenttimemillis ();


Long interval = Endtime-starttime;


System.out.println (Getlistname (list) + ": Insert" +count+ "elements into the 1st position with time:" + interval+ "MS");


}


Deletes the count element from the specified location in the list and counts the time


private static void Deletebyposition (List list) {


Long starttime = System.currenttimemillis ();


Delete the first position element of the list


for (int i=0; i<count; i++)


List.remove (0);


Long endtime = System.currenttimemillis ();


Long interval = Endtime-starttime;


System.out.println (Getlistname (list) + ": delete" +count+ "elements from the 1st position use time:" + interval+ "MS");


}


According to position, constantly read the elements from the list and count the time


private static void Readbyposition (List list) {


Long starttime = System.currenttimemillis ();


Reading the list element


for (int i=0; i<count; i++)


List.get (i);


Long endtime = System.currenttimemillis ();


Long interval = Endtime-starttime;


System.out.println (Getlistname (list) + ": Read" +count+ "elements by position with time:" + interval+ "MS");


}


}





The results of the operation are as follows:


Stack:insert 100000 elements into the 1st position use time:1640 ms


Vector:insert 100000 elements into the 1st position use time:1607 ms


Linkedlist:insert 100000 elements into the 1st position use time:29 ms


Arraylist:insert 100000 elements into the 1st position use time:1617 ms


Stack:read 100000 elements by position use Time:9 ms


Vector:read 100000 elements by position use Time:6 ms


Linkedlist:read 100000 elements by position use time:10809 ms


Arraylist:read 100000 elements by position use Time:5 ms


Stack:delete 100000 elements from the 1st position use time:1916 ms


Vector:delete 100000 elements from the 1st position use time:1910 ms


Linkedlist:delete 100000 elements from the 1st position use time:15 ms


Arraylist:delete 100000 elements from the 1st position use time:1909 ms

From this, we can find:
Inserts 100,000 elements, LinkedList takes the shortest time: 29ms.
Delete 100,000 elements, LinkedList takes the shortest time: 15ms.
Traversing 100,000 elements, the LinkedList takes the longest time: 10809 MS, while ArrayList, stack, and vector are not much different and take only a few seconds.
Considering that the vector supports synchronization and that the stack is inherited from the vector, it concludes that:
(01) for the need to quickly insert, delete elements, you should use LinkedList.
(02) for fast random access elements, you should use ArrayList.
(03)
For a single-threaded environment or multithreaded environment, but the list will only be manipulated by a single thread, you should use a class that is not synchronized at this point.


Analysis of performance difference between LinkedList and ArrayList in the 3rd part
Let's take a look at why inserting elements in LinkedList is very fast, and ArrayList inserts are slow!
The code for inserting an element to a specified location in Linkedlist.java is as follows:

Copy Code code as follows:



Add a node before index, and the value of the node is element


public void Add (int index, E element) {


Addbefore (element, (index==size header:entry (index)));


}


Gets the node at the specified location in a two-way list


Private entry<e> Entry (int index) {


if (Index < 0 | | | index >= size)


throw new Indexoutofboundsexception ("Index:" +index+


", Size:" +size);


entry<e> E = header;


Gets the node at index.


If index < two-way linked list length 1/2, then look backward;


Otherwise, look forward from behind.


if (Index < (size >> 1)) {


for (int i = 0; I <= index; i++)


e = E.next;


} else {


for (int i = size; i > index; i--)


e = e.previous;


}


return e;


}


Add the node (node data is e) before the entry node.


Private entry<e> Addbefore (e E, entry<e> Entry) {


Creates a new node newentry, inserts newentry before node E, and sets the newentry data to be E


entry<e> newentry = new Entry<e> (E, Entry, entry.previous);


Inserting newentry into a linked list


NewEntry.previous.next = Newentry;


newEntry.next.previous = Newentry;


size++;


modcount++;


return newentry;


}





From this we can see that the element is inserted into the LinkedList by the Add (int index, E element). First locate the index in the bidirectional list where you want to insert the node, and then insert a new node after you find it.


Two-way linked list to find the node of index position, there is an acceleration action: if the index < two-way list length of 1/2, then look backward; Otherwise, look forward from behind.


Next, let's look at the code in the Arraylist.java that inserts the element into the specified location. As follows:


Copy Code code as follows:

Add e to the specified location of the ArrayList
public void Add (int index, E element) {
if (Index > Size | | Index < 0)
throw New Indexoutofboundsexception (
"Index:" +index+ ", Size:" +size);
Ensurecapacity (size+1); Increments modcount!!
System.arraycopy (Elementdata, index, Elementdata, index + 1,
Size-index);
Elementdata[index] = element;
size++;
}



The role of Ensurecapacity (size+1) is "to confirm the ArrayList capacity, if not enough capacity, to increase capacity." ”


The real time-consuming operation is system.arraycopy (Elementdata, index, Elementdata, index + 1, size-index);


The arraycopy () declaration in the java/lang/system.java of the Sun JDK package is as follows:


public static native void Arraycopy (object src, int srcpos, object dest, int destpos, int length);


Arraycopy () is a JNI function that is implemented in the JVM. SUNJDK not see the source code, but can be seen in the OPENJDK package source. On-Line has the arraycopy () The analysis explanation, please refer to: system.arraycopy Source code Analysis


In fact, we only need to understand: System.arraycopy (elementdata, index, Elementdata, index + 1, size-index); All elements can be moved after index. This means that ArrayList's Add (int index, E Element) function will cause all elements to change after index!

With the above analysis, we can understand why inserting elements in LinkedList is very fast, and ArrayList is slow to insert elements.
The principle of "delete element" and "Insert Element" is similar, and there is no longer much explanation here.

Next, let's take a look at "Why random access in LinkedList is slow, and random access in ArrayList is fast."
Let's take a look at LinkedList randomly accessed code

Copy Code code as follows:



Returns the element at the specified position in LinkedList


Public E get (int index) {


Return Entry (index). element;


}


Gets the node at the specified location in a two-way list


Private entry&lt;e&gt; Entry (int index) {


if (Index &lt; 0 | | | index &gt;= size)


throw new Indexoutofboundsexception ("Index:" +index+


", Size:" +size);


entry&lt;e&gt; E = header;


Gets the node at index.


If the index &lt; two-way linked list length of 1/2, then the previous search;


Otherwise, look forward from behind.


if (Index &lt; (size &gt;&gt; 1)) {


for (int i = 0; I &lt;= index; i++)


e = E.next;


} else {


for (int i = size; i &gt; index; i--)


e = e.previous;


}


return e;


}





From this we can see that the index element of LinkedList is obtained by getting (int index). First, find the element to index in a two-way list, and then return it after you find it.


Two-way linked list to find the node of index position, there is an acceleration action: if the index &lt; two-way list length of 1/2, then look backward; Otherwise, look forward from behind.


Here's a look at ArrayList randomly accessed code


Copy Code code as follows:

Gets the element value of the index position
Public E get (int index) {
Rangecheck (index);
Return (E) Elementdata[index];
}
private void Rangecheck (int index) {
if (index >= size)
throw New Indexoutofboundsexception (
"Index:" +index+ ", Size:" +size);
}



From this we can see that the index element of ArrayList is obtained by getting (int index). Returns the elements of the index position directly in the array without needing to look like LinkedList.


The 3rd part vector and ArrayList comparison


In the same place


1, they're all list.


They all inherit from Abstractlist and implement the list interface.


The ArrayList and vector classes are defined as follows:


Copy Code code as follows:

Definition of ArrayList
public class Arraylist<e> extends abstractlist<e>
Implements List<e>, Randomaccess, cloneable, java.io.Serializable
The definition of vector
public class Vector<e> extends abstractlist<e>
Implements List<e>, Randomaccess, cloneable, java.io.Serializable {}






2 They all implement the randomaccess and Cloneable interfaces


Implementing randomaccess interfaces means that they all support fast random access;


Implementing the Cloneable interface means that they can clone themselves.





3 They are all implemented by arrays, which are essentially dynamic arrays


Arraylist.java defines array elementdata for saving elements


To save an array of data in ArrayList


Private transient object[] elementdata;


The Vector.java also defines an array elementdata for saving elements


To save an array of data in a vector


protected object[] Elementdata;





4 Their default array size is 10


If the capacity size is not specified when ArrayList or vectors are created, the default capacity size of 10 is used.


The default constructor for ArrayList is as follows:


Copy Code code as follows:

The ArrayList constructor. The default capacity is 10.
Public ArrayList () {
This (10);
}
The default constructor for the vector is as follows:
The Vector constructor. The default capacity is 10.
Public Vector () {
This (10);
}



5 They all support iterator and listiterator traversal


They all inherit from Abstractlist, and the Abstractlist iterator () interface returns iterator iterator and Listiterator () returns the Listiterator iterator respectively.








The difference


1 thread security is not the same


ArrayList is non thread safe;


The vector is thread-safe, and its functions are synchronized, that is, it supports synchronization.


ArrayList applies to single-threaded, and vectors apply to multithreading.


2 different for serialization support


ArrayList supports serialization, which is not supported by vectors, that is, ArrayList has an implementation java.io.Serializable interface and the vector does not implement the interface.


3 The number of constructors is different


The ArrayList has 3 constructors, and the vector has 4 constructors. Vector in addition to including 3 constructors similar to ArrayList, another constructor can specify the capacity increase factor.


The ArrayList constructor is as follows:


Copy Code code as follows:

Default constructor
ArrayList ()
Capacity is the default capacity size for ArrayList. When the capacity is insufficient due to increased data, the capacity adds half of the last capacity size.
ArrayList (int capacity)
Create a ArrayList that contains collection
ArrayList (collection< extends e> Collection)
The vector constructor is as follows:
Default constructor
Vector ()
The capacity is the default capacity size of the vector. When the capacity increases due to increased data, the capacity is increased by one times per volume.
Vector (int capacity)
Create a vector that contains collection
Vector (collection< extends e> Collection)
The capacity is the default capacity size of the vector, and capacityincrement is the increment for each vector capacity increase.
Vector (int capacity, int capacityincrement)



4 Capacity Increase mode different


When adding elements individually, "new capacity" = "(Original capacity x3)/2 + 1" If ArrayList capacity is insufficient.


While the capacity growth of vectors is related to the "growth coefficient", if "growth coefficient" is specified and the "growth coefficient is valid (that is, greater than 0)", then "new capacity" = "raw capacity + growth factor" each time the capacity is insufficient. If the growth factor is invalid (that is, less than/equal to 0), then "new capacity" = "raw capacity x 2".


The main functions of capacity growth in ArrayList are as follows:


Copy Code code as follows:

public void ensurecapacity (int mincapacity) {
To "Modify statistics" +1
modcount++;
int oldcapacity = Elementdata.length;
If the current capacity is insufficient to accommodate the current number of elements, set the new capacity = "(Original capacity x3)/2 + 1"
if (Mincapacity > Oldcapacity) {
Object olddata[] = elementdata;
int newcapacity = (oldcapacity * 3)/2 + 1;
if (Newcapacity < mincapacity)
newcapacity = mincapacity;
Elementdata = arrays.copyof (Elementdata, newcapacity);
}
}



The main functions of capacity growth in vectors are as follows:


Copy Code code as follows:



private void Ensurecapacityhelper (int mincapacity) {


int oldcapacity = Elementdata.length;


Increase capacity when vector capacity is insufficient to accommodate all current elements.


If the capacity increment coefficient is &gt;0 (ie capacityincrement&gt;0), the capacity is increased when capacityincrement


Otherwise, the capacity is increased by one fold.


if (Mincapacity &gt; Oldcapacity) {


object[] OldData = elementdata;


int newcapacity = (capacityincrement &gt; 0)?


(Oldcapacity + capacityincrement): (oldcapacity * 2);


if (Newcapacity &lt; mincapacity) {


newcapacity = mincapacity;


}


Elementdata = arrays.copyof (Elementdata, newcapacity);


}


}








5 support for enumeration is different. Vector supports traversal through enumeration, and list does not support


The code that implements enumeration in the vector is as follows:


Copy Code code as follows:



Public enumeration&lt;e&gt; elements () {


Implementing enumeration with Anonymous classes


return new enumeration&lt;e&gt; () {


int count = 0;


Whether the next element exists


public boolean hasmoreelements () {


return count &lt; Elementcount;


}


Get Next element


Public E nextelement () {


Synchronized (vector.this) {


if (Count &lt; Elementcount) {


Return (E) elementdata[count++];


}


}


throw new Nosuchelementexception ("Vector enumeration");


}


};


}


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.