2015-02-05 50 views
0

我有一個關於這個的foreach問題:Java foreach是否創建副本?

for(Element e : nullProof(setOfElements)){ 
      // do stuff 
    } 

假設我定義的函數,nullProof,返回一個非空集(因爲我聽說你不應該爲空進入一個增強的for循環。這是真的):

private Set<Element> nullProof(Set<Element> s){ 
      return s == null ? Collections.<Element> emptySet() : s; 
    } 

我的問題是...是安全調用的foreach內nullProof功能?具體來說,就是下面的標題等同於:

for(Element e : setOfElements){ //assuming setOfElements != null 

我想知道,如果有人可以點我的一些Java標準說,這是定義的行爲。

此外,有人可以解釋當這個foreach被調用時,「幕後」實際發生了什麼嗎?

比方說setOfElements已尺寸6.通過setOfElements每次迭代,並在JVM查找setOfElements 6不同的時間,或者它創建一個集的副本,並參考副本?我試圖理解這種行爲。謝謝您的幫助!

+2

查看http://stackoverflow.com/questions/85190/how-does-the-java-for-each-loop-work – keuleJ 2015-02-05 18:54:19

+0

你是什麼意思?「擡頭?「 – 2015-02-05 19:03:01

回答

6

是的,它是完全安全的。

for(Element e : nullProof(setOfElements)) { 

相當於

Set<Element> s = nullProof(setOfElements); 
for(Element e : s) { 

JLS-14現場的每個循環的背後說明等同於:

for(Iterator<Element> it = s.iterator() ; it.hasNext() ;) { 
    Element e = it.next(); 
    // ... 
} 
+0

太棒了,謝謝你的JLS-14鏈接。我會給它一個閱讀,謝謝 – 2015-02-05 19:22:08

2

它是安全的,因爲實際的集合必須在任何迭代發生之前解決,但它在一定程度上掩蓋了你的意圖。在我看來,這是清晰的:

if (setOfElements != null) { 
    for (Element e : setOfElements) { 
     ... 
    } 
} 

或者,您可能需要重新評估爲什麼你讓setOfElementsnull的。首先將它列爲空列表是否有意義,而不是null


假設setOfElements有大小6.對於每個迭代通過setOfElements,並在JVM查找setOfElements 6不同的時間,或者它創建一個集的副本,並參考副本?我試圖理解這種行爲。

不涉及複製。增強型for -loop使用Iterator(由任何集合的iterator方法返回)來執行迭代。 Iterator是一個能夠通過next方法逐個給出某些集合的元素的對象。