2011-03-15 185 views
3

我在理解for-each循環時遇到了問題。我熟悉w/for-each的典型結構,其中每個元素都有計數器和賦值語句。但是,在下面的代碼中,「新」關鍵字暗示了什麼?它只執行一次嗎?For Each Loop問題

for(Integer item : new ArrayList<Integer>(myCollection)){ 
    myCollection.add(first.intValue() + item.intValue()); 
} 

這相當於下面的循環嗎?

for(int ctr = 0; ctr < myCollection.size(); ctr++){ 
    Integer temp = myCollection.get(ctr); 
    myCollection.add(first.intValue() + item.intValue()); 
} 
+0

我假設你想要一個first.intValue()而不是第一個,intValue() –

+0

沒有人提到一個LinkedList <> myCollection的O(n^2)? –

回答

4

new關鍵詞意味着它將創建一個新的ArrayList,就像它在代碼中的其他地方一樣。

該代碼與以下內容基本相同。在for-each循環中使用new沒有什麼特別之處。

List<Integer> list = new ArrayList<Integer>(myCollection); 
for(Integer item : list){ 
    myCollection.add(first.intValue() + item.intValue()); 
} 

它與您的替代循環不一樣,因爲size()會在添加內容時發生變化。我假設你打算用於ctri是一樣的。它相當於

for(int i = 0, size = myCollection.size(); i < size; i++){ 
    myCollection.add(first.intValue() + myCollection.get(i).intValue()); 
} 

我想象的一樣

for(int i = 0, size = myCollection.size(); i < size; i++) 
    myCollection.add(first + myCollection.get(i)); 
+1

感謝您的詳細回覆!幫了很多! – maru

2

第一個代碼塊創建的IntegersArrayList,拷貝在所得ArrayList所述的myCollection內容到它,然後進行迭代。

由於原始myCollection在循環內被修改,所以需要複製副本。

第二個代碼塊與第一個代碼塊不同,因爲它在迭代它時向myCollection添加了元素。由於這種互動,它不會做你期望的事情,並會導致無限循環。

+0

迂腐,而不是進入無限循環,ArrayList只能有2^31-1個元素。事實上,它將停止在14億美元左右,因爲它在這一點上試圖增長到超過這個數量。 ;)如果你使用LinkedList,它會停在Integer.MAX_VALUE,因爲這是最大尺寸()可以返回。 –

0

您提供的是非常相似的兩個代碼,但主要差(new關鍵字存在)是第一代碼您正在創建原始列表的副本。這是必需的,因爲在循環內部,您將向列表中添加更多項目,從而增加其大小。這樣,循環永遠不會退出,最終你將獲得內存。

使用for(;;)將下面的等效代碼:

List<Integer> auxList = new ArrayList<Integer>(myCollection); 
for(int ctr = 0; ctr < auxList.size(); ctr++){ 
    myCollection.add(first.intValue() + auxList.get(ctr)); 
} 

或者你可以簡單地預先計算的大小,以避免此驗證碼:

int size = myCollection.size(); 
for(int ctr = 0; ctr < size; ctr++){ 
    myCollection.add(first.intValue() + myCollection.get(ctr)); 
} 

除此之外,唯一不同的是, foreach方法使用迭代器而不是索引訪問元素。

希望它有幫助!

0

它只執行一次嗎?

是的。

這相當於下面的for循環嗎?

號你的循環,如下

  1. 有三個錯誤(first,intValue(),循環索引是ctrmyCollection.get(i),你取到temp離開item未定義),
  2. 迭代myCollection,加入到它不斷地檢查一個不斷增長的尺寸,因此它不會終止(size()越來越多),除了它
  3. 最終會拋出一個OutOfMemoryError

它是,但是,相當於本

for (int i = 0, n = myCollections.size(); i < n; i++) { 
    Integer item = myCollection.get(i); 
    myCollection.add(first.intValue() + item.intValue()); 
} 
0

您的循環

for(Integer item : new ArrayList<Integer>(myCollection)){ 
    myCollection.add(first.intValue() + item.intValue()); 
} 

被編譯成相同的代碼(模變量名)作爲

for (Iterator<Integer> iterator = new ArrayList<Integer>(myCollection).iterator(); 
    it.hasNext();) { 
    Integer item = iterator.next(); 
    myCollection.add(first.intValue() + item.intValue()); 
} 

如果myCollection的大小不會改變(和myCollecti上是List),那麼這將是唯一的效率較低的爲

for(int ctr = 0; ctr < myCollection.size(); ctr++){ 
    Integer temp = myCollection.get(i); 
    myCollection.add(first.intValue() + temp.intValue()); 
} 

創建臨時表)相同的(...但你正在改變myCollection循環內,所以這第二循環將永遠不會到達結束(假設至少有一個元素在其中)。

所以你的ArrayList有助於讓你的循環良好的表現。