1. 程式人生 > >iterator 遍歷與for迴圈與foreach的優劣對比

iterator 遍歷與for迴圈與foreach的優劣對比

最近看到專案上有這樣的語句

 Iterator it = list.iterator();
    while (it.hasNext()) {
        objects = (Object[]) iter.next();
    }

瞬間感覺比起自己的for迴圈語句高階大氣了不少,但此刻又有疑問,到底這兩種那種比較好

先拿出for迴圈來對比

for(int i=0;i <list.size();i++){ 
      objects = (Object[])list.get(i); 

經過查詢,查到了很多,現在來分享一下

一方面從簡潔程度和可複用的角度,迭代器的方法必然比較輕鬆 ,比如當前list的組織結構變化,不能用get()函式獲取,則需要重新更改for迴圈程式碼,而迭代器不用,故這是開發愛好者比較喜歡的一種程式碼方式

至於效率方面,找到了一位大神的測試分析http://bbs.csdn.net/topics/250025827

現在拷貝一些關鍵資料

import java.util.Iterator;
import java.util.List;
import java.util.ArrayList;
import java.util.LinkedList;

/**
 * IteratorTest
 * @author SageZk
 */
public class IteratorTest {

	public static long testForloops(List<String> list) {
		long start = 0L, end = 0L;
		@SuppressWarnings("unused")
		String le = null;
		start = System.nanoTime();
		for (int i = list.size() - 1; i >= 0; --i) {
			le = list.get(i);
		}
		end = System.nanoTime();
		return end - start;
	}

	public static long testIterator(List<String> list) {
		long start = 0L, end = 0L;
		@SuppressWarnings("unused")
		String le = null;
		start = System.nanoTime();
		Iterator<String> it = list.iterator();
		while (it.hasNext()) {
			le = it.next();
		}
		end = System.nanoTime();
		return end - start;
	}

	public static void main(String[] args) {
		//測試列表長度
		final int LEN = 10000;

		//初始化測試用資料
		List<String> arraylist = new ArrayList<String>();
		List<String> linkedlist = new LinkedList<String>();
		for (int i = 0; i < LEN; ++i) {
			String s = Integer.toString(i, 2);
			arraylist.add(s);
			linkedlist.add(s);
		}

		//列印測試結果
		final String FORMAT = "%1$-16s%2$-16s%3$16d\n";
		System.out.println("List\t\tType\t\tTime(nanoseconds)");
		System.out.println("-------------------------------------------------");
		System.out.printf(FORMAT, "ArrayList", "for", testForloops(arraylist));
		System.out.printf(FORMAT, "ArrayList", "Iterator", testIterator(arraylist));
		System.out.printf(FORMAT, "LinkedList", "for", testForloops(linkedlist));
		System.out.printf(FORMAT, "LinkedList", "Iterator", testIterator(linkedlist));
	}

}

以下是 3 組測試結果:

[code=BatchFile]List Type Time(nanoseconds)
-------------------------------------------------
ArrayList       for                      1189258
ArrayList       Iterator                 2365594
LinkedList      for                    152396254
LinkedList      Iterator                 2340801

List Type Time(nanoseconds)


-------------------------------------------------
ArrayList       for                      1235701
ArrayList       Iterator                 4249982
LinkedList      for                    149825606
LinkedList      Iterator                 2525531

List Type Time(nanoseconds)
-------------------------------------------------
ArrayList       for                      1198267
ArrayList       Iterator                 2584617
LinkedList      for                    150382451
LinkedList      Iterator                 2347994
[/code]

這裡可以看出當用linkedlist的方式時用iterator明顯好很多

這時又有人提出,可以用foreach來編寫,這樣更加簡略

List <String> list = new ArrayList <String>(); 
for (String s:list) { 
    System.out.println(s); 

這時,本著比對的態度,網上進行了查閱,首先從java forEach實現原理可以參見下文http://blog.csdn.net/a596620989/article/details/6930479

我們可以看到foreach其實就是迭代器,而且多加了一個一個檢查

但foreach又有什麼壞處呢

通過http://lavasoft.blog.51cto.com/62575/53321/

我們可以看到結論:

foreach語句是for語句特殊情況下的增強版本,簡化了程式設計,提高了程式碼的可讀性和安全性(不用怕陣列越界)。相對老的for語句來說是個很好的補充。提倡能用foreach的地方就不要再用for了。在用到對集合或者陣列索引的情況下,foreach顯得力不從心,這個時候是用for語句的時候了。