To Java programmer: Do not traverse linkedlist with normal for loop

Source: Internet
Author: User

ArrayList and LinkedList normal for loop traversal

For most Java programmer friends, it is possible to use the most commonly used list is ArrayList, for ArrayList traversal, generally use the following wording:

void Main (string[] args) {    list<integer> arrayList =             new arraylist<integer> for(  int i = 0; I < 100; i++ for(int i = 0; i <; i++) System.out.println (Arraylist.get (i));}     

If you want to use LinkedList in the future, maybe some friends will go through the linkedlist in the same way:

void Main (string[] args) {    list<integer> LinkedList =             new linkedlist<integer> for( int i = 0; i < i++ for(int i = 0; i < i++) System.out.println (Linkedlist.get (i));} 

Keep in mind: This is a very bad practice . This is actually not the Java problem, but the data structure of the problem, I believe the language from Java to other things are the same.

The following is a test of the average for loop efficiency of ArrayList and LinkedList and the reason for analysis.

ArrayList and LinkedList use normal for loop traversal speed comparison

Give the test code first:

PublicClasslistiteratortest{PrivateFinalStaticint list_size = 1000;PublicStaticvoidMain (string[] args) {list<integer> arrayList =New arraylist<integer>(); list<integer> LinkedList =New linkedlist<integer>();for (int i = 0; i < list_size; I++) {Arraylist.add (i); Linkedlist.add (i);} long startTime = System.currenttimemillis (); for (int i = 0; i < arraylist.size (); I++) Arraylist.get (i); SYSTEM.OUT.PRINTLN ("ArrayList traversal Speed:" + (System.currenttimemillis ()-StartTime) + "MS" ) ; StartTime = System.currenttimemillis (); for (int i = 0; i < linkedlist.size (); I++) Linkedlist.get (i); SYSTEM.OUT.PRINTLN ("LinkedList traversal Speed:" + (System.currenttimemillis ()-StartTime) + "MS" 

Increasing list_size, I use a table to represent the results of the operation:

1000 5000 10000 50000 100000
ArrayList 0ms 1ms 2ms 3ms 3ms
LinkedList 3ms 16ms 88ms 2446ms 18848ms

From the running results we see, by multiples increase the list capacity, ArrayList traversal seems relatively stable, and the linkedlist of the traversal is almost explosive growth, it is not necessary to test again.

The following explains why this behavior occurs.

ArrayList the reason for using normal for loops to traverse fast

First look at the ArrayList get method source code:

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

Seeing ArrayList's Get method just takes a position element from the array. We have concluded that thetime complexity of the Get method of the ArrayList is O (1), O (1) meaning that the time complexity is a constant, and the size of the array is not related, as long as the location of the given arrays, directly can locate the data.

In fact, familiar with C, C + + or pointers to the understanding of the friend must be very good understanding why, I explain why the use of an array get fast.

At the bottom of the computer, the data is addressed, just like a person has an address. Suppose I write a code like this:

Int[3] INTs = {1, 3, 5};

In Java, an int data is 4 bytes, and what is done inside the computer is to find a contiguous memory space in the memory space that is sufficient to hold 3 4-byte, 12-byte arrays, and return the first address of that memory space. For example, the first address of the memory space is 0x00, then 1 is placed in the 0x00~0x03, 3 in 0x04~0x07, 5 in the 0x08~0x0b.

At this point it is very simple, take ints[1], the computer will calculate the ints[1] data is stored in the beginning of the 0x04, occupies 4 bytes of memory, so the computer will read from the 0x04~0x07 this address space data.

The whole process, and how big the array is, does not matter, the computer does just work out the starting address--to go to the address to fetch data , so we see that using the normal for loop to traverse the ArrayList is very fast and stable.

LinkedList the reason for slow traversal using normal for loop

Take a look at what the LinkedList get method does:

Public E get (int index) {    return entry (index). element;}
1Private Entry<e> Entry (IntIndex) {2if (Index < 0 | | | Index >=Size3ThrowNew Indexoutofboundsexception ("Index:" +index+4 ", Size:" +size);5 entry<e> E =Header6if (Index < (size >> 1 7 for (int i = 0; I <= index; I++)  8 E = E.next; 9} else {10 for (int i = size; i > Index; i--) 11 e = E.previous; }13 return E; 14}             

Since LinkedList is a doubly linked list, the 6th line means to calculate I in half before or half, half before the positive sequence traversal, half after the reverse traversal, this will be much faster, of course, regardless of this, analyze why the use of ordinary for loop traversal LinkedList will be so slow.

The reason is in line 8th of 7~, the first of the two for-following in line 10~ 11th, taking the former as an example:

1, get (0), directly get the address of the 0-bit Node0, get the data inside the NODE0

2, get (1), directly to the address of the 0-bit Node0, from the 0-bit Node0 find the next 1-bit Node1 address, find Node1, get the data inside the Node1

3, Get (2), directly get the address of the 0-bit Node0, find the next 1-bit Node1 address from the 0-bit Node0, find the Node1, find the next 1-bit Node1 address from the 2-bit Node2, find the Node2, get the data inside the Node2.

Later and so on.

That is,LinkedList will go through the data at the time of the get data at any location . If I have 10 data, then will query 1+2+3+4+5+5+4+3+2+1=30 data, compared to ArrayList, but only need to query 10 times the data on the line, with the linkedlist capacity, the gap will be larger. In fact, the use of LinkedList in the end to query how many times the data, we should have been very clear, to calculate: According to the first half should be (1 + 0.5N) * 0.5N/2, after half count is multiplied by 2, should be (1 + 0.5N) * 0.5N = 0.25N2 + 0.5N, ignoring low Order and first coefficients, it is concluded that the time complexity of linikedlist traversal is O (N2)andN is the capacity of LinkedList .

Time complexity has the following rules of thumb:

O (1) < O (log2n) < O (n) < O (n * log2n) < O (N2) < O (N3) < 2N < 3N < n!

The first four are better, the middle two general, and the last 3 are rotten. That is to say O (N2) is a relatively bad time complexity, n a little bit, the program will be executed relatively slowly.

Postscript

According to the above analysis, you Java programmer Friends, remember must not use ordinary for loop to traverse LinkedList. Using an iterator or a foreach loop (the principle of the Foreach loop is an iterator) is to traverse the LinkedList, which is to go directly to the address to find the data, will greatly improve the efficiency of traversing linkedlist.

To Java programmer: Do not traverse linkedlist with normal for loop

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.