2015-12-02 451 views
1

我的情況是,我有一個類Foo:Groovy中的「each」和「eachWithIndex」是否會生成深度副本或淺度副本?

class Foo { 
List<Bar> barList; 
//other stuff 
} 

,然後我想做的事:

void process (Foo obj){ 
obj.getBarList().each { 
Bar bar -> 
bar = doSomeStuff(bar) 
} 
} 

請問此更新的對象foo的barList屬性?或者將我必須做一些事情,如:

void process (Foo obj){ 
obj.getBarList().eachWithIndex { 
Bar bar -> 
bar = doSomeStuff(bar) 
obj.getBarList().set(bar, index) 
} 
} 
+4

它根本不會生成副本;它提供了列表中每個項目的參考。如果'doSomeStuff'在該引用上運行,那麼該列表將在原地進行修改。不管這是否是一種好的做法是一個單獨的討論(這很可怕,因爲你現在必須理解兩塊代碼才能推斷髮生了什麼)。 –

回答

1

對於你的第一個代碼示例:

void process (Foo obj) { 
    obj.getBarList().each { 
     Bar bar -> bar = doSomeStuff(bar) } 
} 

在符列表欄obj是不會被修改,這意味着在列表中的參考文獻仍然是相同的。當doSomeStuff(bar)修改條形對象時,被引用的對象被修改,但是沒有辦法從你的代碼中知道。

由於bar是按值傳遞的,因此賦值bar = doSomeStuff(bar)不會更改列表中的引用(請參見Is Java pass by reference or pass by value?)。

您的第二個代碼示例將更改列表中的引用對象。

我會建議保持你的酒吧對象不變,並創建一個全新的列表與聚集操作:

void process (Foo obj) { 
    obj.bar = obj.bar.collect { doSomeStuff(it) } 
} 

這很容易看出這是怎麼回事且不易出錯恕我直言。

相關問題