java中三種for循環之間的對比


普通for循環語法:

1 for (int i = 0; i < integers.length; i++) {  
2     System.out.println(intergers[i]);  
3 }  

foreach 循環語法:

1 for(Integer in : integers){  
2     System.out.println(in);  
3 }  

今天我們來比較一下兩種for循環對ArrayList和LinkList集合的循環性能比較。首先簡單的了解一下ArrayList和LinkList的區別:

ArrayList:ArrayList是采用數組的形式保存對象的,這種方式將對象放在連續的內存塊中,所以插入和刪除時比較麻煩,查詢比較方便。

LinkList:LinkList是將對象放在獨立的空間中,而且每個空間中還保存下一個空間的索引,也就是數據結構中的鏈表結構,插入和刪除比較方便,但是查找很麻煩,要從第一個開始遍歷。

 

下面是我測試的代碼:

 1 package cn.migu.newportal.activity.service.activity;
 2 
 3 import java.util.ArrayList;
 4 import java.util.LinkedList;
 5 import java.util.List;
 6 
 7 /**
 8  *
 9  * @author 
10  * @version C10 2017年11月30日
11  * @since SDP V300R003C10
12  */
13 public class Test
14 {
15     public static void main(String[] args)
16     {
17         
18         // 實例化arrayList
19         List<Integer> arrayList = new ArrayList<Integer>();
20         // 實例化linkList
21         List<Integer> linkList = new LinkedList<Integer>();
22         
23         // 插入10萬條數據
24         for (int i = 0; i < 100000; i++)
25         {
26             arrayList.add(i);
27             linkList.add(i);
28         }
29         
30         int array = 0;
31         // 用for循環arrayList
32         long arrayForStartTime = System.currentTimeMillis();
33         for (int i = 0; i < arrayList.size(); i++)
34         {
35             array = arrayList.get(i);
36         }
37         long arrayForEndTime = System.currentTimeMillis();
38         System.out.println("用for循環arrayList 10萬次花費時間:" + (arrayForEndTime - arrayForStartTime) + "毫秒");
39         
40         // 用foreach循環arrayList
41         long arrayForeachStartTime = System.currentTimeMillis();
42         for (Integer in : arrayList)
43         {
44             array = in;
45         }
46         long arrayForeachEndTime = System.currentTimeMillis();
47         System.out.println("用foreach循環arrayList 10萬次花費時間:" + (arrayForeachEndTime - arrayForeachStartTime) + "毫秒");
48         
49         // 用for循環linkList
50         long linkForStartTime = System.currentTimeMillis();
51         int link = 0;
52         for (int i = 0; i < linkList.size(); i++)
53         {
54             link = linkList.get(i);
55         }
56         long linkForEndTime = System.currentTimeMillis();
57         System.out.println("用for循環linkList 10萬次花費時間:" + (linkForEndTime - linkForStartTime) + "毫秒");
58         
59         // 用froeach循環linkList
60         long linkForeachStartTime = System.currentTimeMillis();
61         for (Integer in : linkList)
62         {
63             link = in;
64         }
65         long linkForeachEndTime = System.currentTimeMillis();
66         System.out.println("用foreach循環linkList 10萬次花費時間:" + (linkForeachEndTime - linkForeachStartTime) + "毫秒");
67     }
68 }

循環10萬次的時候,控制台打印結果:  (結果每次都會變,但求個平均值還是可以分析出結果的)

用for循環arrayList 10萬次花費時間:6毫秒
用foreach循環arrayList 10萬次花費時間:7毫秒
用for循環linkList 10萬次花費時間:20489毫秒
用foreach循環linkList 10萬次花費時間:8毫秒

 

 

可以看出,循環ArrayList時,普通for循環比foreach循環花費的時間要少一點;循環LinkList時,普通for循環比foreach循環花費的時間要多很多。

 

當我將循環次數提升到一百萬次的時候,循環ArrayList,普通for循環還是比foreach要快一點;但是普通for循環在循環LinkList時,程序直接卡死。

 

結論:需要循環數組結構的數據時,建議使用普通for循環,因為for循環采用下標訪問,對於數組結構的數據來說,采用下標訪問比較好。

需要循環鏈表結構的數據時,一定不要使用普通for循環,這種做法很糟糕,數據量大的時候有可能會導致系統崩潰。

 

 

網上參考一種代碼更緊湊的寫法:

 

實體Person類

 1 package cn.migu.newportal.activity.service.activity;
 2 
 3 /**
 4  *
 5  * @author 
 6  * @version C10 2017年11月30日
 7  * @since SDP V300R003C10
 8  */
 9 public class Person
10 {
11     private String a;
12     
13     private int b;
14     
15     public Person(String a, int b)
16     {
17         super();
18         this.a = a;
19         this.b = b;
20     }
21     
22     public String getA()
23     {
24         return a;
25     }
26     
27     public void setA(String a)
28     {
29         this.a = a;
30     }
31     
32     public int getB()
33     {
34         return b;
35     }
36     
37     public void setB(int b)
38     {
39         this.b = b;
40     }
41     
42 }

測試ArrayList的主程序:

 1 package com.zhang.loop;  
 2   
 3 import java.util.ArrayList;  
 4 import java.util.Iterator;  
 5 import java.util.LinkedList;  
 6 import java.util.List;  
 7   
 8 public class TestArrayList {  
 9     private static final int COUNT = 800000;  
10     private static List<Person> persons = new ArrayList<Person>();  
11       
12     public static void main(String[] args) {  
13         init();  
14         System.out.println("for循環測試結果:"+testFor());  
15         System.out.println("foreach循環測試結果:"+testForeach());  
16         System.out.println("iterator循環測試結果:"+testIterator());  
17     }  
18       
19     //初始化集合  
20     public static void init(){  
21         for (int i = 0; i <COUNT; i++) {  
22             persons.add(new Person("第"+i+"個元素",i));  
23         }  
24     }  
25     //for循環便利集合  
26     public static long testFor(){  
27         long start = System.nanoTime();  
28         Person p = null;  
29         for (int i = 0; i < persons.size(); i++) {  
30             p = persons.get(i);  
31         }  
32         return (System.nanoTime()-start)/1000;  
33     }  
34     //foreach循環便利集合  
35     public static long testForeach(){  
36         long start = System.nanoTime();  
37         Person p = null;  
38         for (Person person : persons) {  
39             p = person;  
40         }  
41         return (System.nanoTime()-start)/1000;  
42     }  
43     //iterator循環便利集合  
44     public static long testIterator(){  
45         long start = System.nanoTime();  
46         Person p = null;  
47         Iterator<Person> itreator = persons.iterator();  
48         while(itreator.hasNext()){  
49             p = itreator.next();  
50         }  
51         return (System.nanoTime()-start)/1000;  
52     }  
53       
54 }  

ArrayList測試結果:

測試LinkedList的主程序:

 1 package com.zhang.loop;  
 2   
 3 import java.util.ArrayList;  
 4 import java.util.Iterator;  
 5 import java.util.LinkedList;  
 6 import java.util.List;  
 7   
 8 public class TestArrayList {  
 9     private static final int COUNT = 8000;  
10     private static List<Person> persons = new LinkedList<Person>();  
11       
12     public static void main(String[] args) {  
13         init();  
14         System.out.println("for循環測試結果:"+testFor());  
15         System.out.println("foreach循環測試結果:"+testForeach());  
16         System.out.println("iterator循環測試結果:"+testIterator());  
17     }  
18       
19     //初始化集合  
20     public static void init(){  
21         for (int i = 0; i <COUNT; i++) {  
22             persons.add(new Person("第"+i+"個元素",i));  
23         }  
24     }  
25     //for循環便利集合  
26     public static long testFor(){  
27         long start = System.nanoTime();  
28         Person p = null;  
29         for (int i = 0; i < persons.size(); i++) {  
30             p = persons.get(i);  
31         }  
32         return (System.nanoTime()-start)/1000;  
33     }  
34     //foreach循環便利集合  
35     public static long testForeach(){  
36         long start = System.nanoTime();  
37         Person p = null;  
38         for (Person person : persons) {  
39             p = person;  
40         }  
41         return (System.nanoTime()-start)/1000;  
42     }  
43     //iterator循環便利集合  
44     public static long testIterator(){  
45         long start = System.nanoTime();  
46         Person p = null;  
47         Iterator<Person> itreator = persons.iterator();  
48         while(itreator.hasNext()){  
49             p = itreator.next();  
50         }  
51         return (System.nanoTime()-start)/1000;  
52     }  
53       
54 }  

LinkedList測試結果:

記錄的存取方式有兩種:

             一種是順序存儲(數組,ArrayList..)可以根據其下標找到對應的記錄

            另一種是鏈接存儲(LinkedList..)鏈接存儲(拿單鏈表為例)則必須找到其前一個記錄的位置才能夠找到本記錄。

 

根據以上可以得到的結果是:for循環便於訪問順序存儲的記錄而foreach和迭代器便於訪問鏈接存儲


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM