1

My situation is that I have a class Foo:

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

and then I want to do:

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

Will this update the barList attribute in object foo? Or will I have to do something like:

void process (Foo obj){
obj.getBarList().eachWithIndex {
Bar bar ->
bar = doSomeStuff(bar)
obj.getBarList().set(bar, index)
}
}
ankit
  • 350
  • 2
  • 7
  • 12
  • 4
    It doesn't produce copies at all; it provides a reference to each item in the list. If `doSomeStuff` operates on that reference then the list will be modified in-place. Whether or not that's a good practice is a separate discussion (it's scary, because you now have to understand two chunks of code in order to reason about what's happening). – Dave Newton Dec 02 '15 at 22:13

1 Answers1

1

For your first code example:

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

The List bar in Foo obj is not modified, meaning the references in the list are still the same. When doSomeStuff(bar) modifies the bar objects then the referenced objects are modified but there's no way to tell from your code.

The assignment bar = doSomeStuff(bar) doesn't change the references in the list since bar is passed by value (See Is Java pass by reference or pass by value?).

Your second code example would change the referenced objects in the list.

I would recommend keeping your Bar objects immutable and create a whole new List with a collect operation:

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

It's easier to see what's going on and less error prone IMHO.

Community
  • 1
  • 1
Emanuel Seidinger
  • 1,272
  • 1
  • 12
  • 21