2015-02-24 84 views
7

我找不到任何關於此的主題。我想知道這是否是安全的像一個波紋管的循環過程中更改列表類的引用:在Java循環期間更改了列表對象引用

Tree minimalTree = someTree; 
for (Tree st : minimalTree.getSubtrees()) { 
    if (condition) 
    minimalTree = st; 
} 

是否迭代被複位,爲新的參考重新開始?

編輯:我忘了說:這段代碼適用於我想要縮小樹中元素搜索範圍的情況,比方說,包含某些元素的較小的樹。在這種情況下,繼續只查看「minimalTree」的內部結構而不是整個「someTree」結構會更快。

+1

會發生什麼事,當你測試它? – 2015-02-24 21:04:03

+0

您應該爲此使用遞歸調用。 – biziclop 2015-02-24 21:16:05

+0

直到現在它似乎仍能正常工作,但我不確定它是否可以用於大規模處理。但也許@biziclop是正確的,應避免這種編碼... – 2015-02-24 21:19:27

回答

6

不,重複不會被重置。按照JLS

增強的for語句等價於一個基本爲 聲明形式:

for (I #i = Expression.iterator(); #i.hasNext();) { 
    {VariableModifier} TargetType Identifier = (TargetType) #i.next(); 
    Statement 
} 

的定義,使其明顯迭代器只初始化一次,前循環的第一次迭代。

使用增強for語句遍歷數組時的行爲在這方面是類似的。

但是我個人認爲它很糟糕的做法,因爲它使代碼很難理解。

2

實際上,有兩個問題:

我想知道這是否是安全的像一個波紋管的循環過程中更改列表類的引用:

是的,是安全的。爲了安全,我的意思是:改變參考不會干擾已經運行的循環。

迭代器是否重置並重新啓動新引用?

不,迭代器不會重置。這完全與安全相反。

在我看來,改變循環內的迭代器或集合變量並不是一個好習慣。它使代碼更難理解,並且可能結果不是你期望的結果(就像你的情況,我理解你期望循環開始重新評估集合)。

在你的情況,在封裝的方法和遞歸調用它的子樹:

Tree findMinimalTree(Tree tree) { 
    for (Tree st : tree.getSubtrees()) { 
    if (condition) 
     return findMinimalTree(st); 
    } 
    return tree; 
} 
+0

我不同意。閱讀biziclop的答案。用我的話來說,minimalTree.getSubtrees()[。iterator()]在進入循環時被精確計算一次。之後,你可以讓minimalTree指向任何你想要的。記住assigment minimalTree = st不會改變之前由minimalTree引用的對象(這裏C++會做的事情)。它只是改變參考minimalTree,我。即minimalTree指向的對象。 – fjf2002 2015-02-24 21:40:25

+0

是的,我瞭解你的觀點。在我看來,問題是(i)乍一看似乎像C++對應物一樣工作,並且(ii)當您調試時,您無法看到您正在迭代的集合。 – 2015-02-24 21:50:53

+0

「這似乎工作」不是表達這一點的適當方式,我會盡力改善它。有什麼建議麼? – 2015-02-24 21:54:09