| Author |
Collections.unmodifiable* and Immutability
|
Perry Terrance
Ranch Hand
Joined: Oct 02, 2009
Posts: 46
|
|
I know this is probably answered before, but can anyone give me a quick answer on this.
If I do a Collections.unmodifiableMap - the returned Map is immutable (read-only), but what about the elements inside the Map? If the Map itself was filled with a bunch of different objects such as HashTables, Arrays, etc, can I modify them? Or is this whole unmodifiable property a recursive one - that goes down all the object layers inside?
|
 |
Jeff Verdegan
Bartender
Joined: Jan 03, 2004
Posts: 5844
|
|
Perry Terrance wrote:I know this is probably answered before, but can anyone give me a quick answer on this.
If I do a Collections.unmodifiableMap - the returned Map is immutable (read-only), but what about the elements inside the Map?
Both the keys and the values are precisely as mutable as they were before. The only thing unmodifiableXxx() does is prevent you from changing the structure of the collection--can't add, remove, rearrange.
It is a "shallow" immutability.
|
 |
Paul Clapham
Bartender
Joined: Oct 14, 2005
Posts: 16483
|
|
Perry Terrance wrote:If I do a Collections.unmodifiableMap - the returned Map is immutable (read-only), but what about the elements inside the Map? If the Map itself was filled with a bunch of different objects such as HashTables, Arrays, etc, can I modify them? Or is this whole unmodifiable property a recursive one - that goes down all the object layers inside?
It just makes the returned Map unmodifiable. That's all. If it did do something ambitious like having the get() methods return unmodifiable versions of the objects in the Map, you can be sure that the documentation would mention that. And it doesn't.
|
 |
Perry Terrance
Ranch Hand
Joined: Oct 02, 2009
Posts: 46
|
|
Thanks!
Just the thing I needed was this exact setup!
So "shallow" immutability is what I need since I need to tinker with the actual objects inside the Map...
On a side note, I wonder if there was ever a way to do this recursively though, if I ever wanted a full-recursive immutability...
|
 |
Paul Clapham
Bartender
Joined: Oct 14, 2005
Posts: 16483
|
|
Perry Terrance wrote:On a side note, I wonder if there was ever a way to do this recursively though, if I ever wanted a full-recursive immutability...
The minimum requirement for that (I think) would be to be able to make an unmodifiable version of an arbitrary object. This would require returning a wrapper, or a proxy, or something like that. And that proxy would have to throw an exception when something called any method which would have modified the state of the original object.
And that's the hard part. How can you tell whether a method is going to modify the state of an object?
I'm not saying that couldn't be done. I just think it would take some heavy-duty techniques like (for example) the tricks Hibernate uses to tell when you've updated a Hibernate object.
|
 |
Jeff Verdegan
Bartender
Joined: Jan 03, 2004
Posts: 5844
|
|
Perry Terrance wrote:
So "shallow" immutability is what I need since I need to tinker with the actual objects inside the Map...
Be careful though. If you change the contents of a key in a way that affects the results of hashCode(), the map may not be able to find that key. You should generally use only immutable objects for Map keys and Set entries, or else be very careful not to change their states after adding them.
On a side note, I wonder if there was ever a way to do this recursively though, if I ever wanted a full-recursive immutability...
To a limited extent, yes. You could create your own Map implementation (either extend, or better yet, delegate to) an existing implementation. You then have to tell each element to make itself immutable. This means you can only use classes you write (or that are already immutable) as elements.
|
 |
Winston Gutkowski
Bartender
Joined: Mar 17, 2011
Posts: 4747
|
|
Perry Terrance wrote:I know this is probably answered before, but can anyone give me a quick answer on this.
If I do a Collections.unmodifiableMap - the returned Map is immutable (read-only), but what about the elements inside the Map? If the Map itself was filled with a bunch of different objects such as HashTables, Arrays, etc, can I modify them? Or is this whole unmodifiable property a recursive one - that goes down all the object layers inside?
The best analogy I can give you is that it's like being passed an array as a parameter. You can't change the array itself, but you can change one of the elements if the element type itself is mutable. In fact, it slightly more restrictive, because with an array you can replace an element; with an unmodifiable collection you can't.
HIH
Winston
|
Isn't it funny how there's always time and money enough to do it WRONG?
|
 |
Jeff Verdegan
Bartender
Joined: Jan 03, 2004
Posts: 5844
|
|
|
Correction withdrawn, as Winston has gone back and clarified his post.
|
 |
Winston Gutkowski
Bartender
Joined: Mar 17, 2011
Posts: 4747
|
|
Jeff Verdegan wrote:Sorry, but that analogy doesn't quite hold. If you're passed an array, you can change the value of one of the array's elements.
Blimey, you're quick! I was just correcting the post and got a 'caught us doing modificiations' message when I sent. See updated version now.
Winston
|
 |
 |
|
|
subject: Collections.unmodifiable* and Immutability
|
|
|