views:

109

answers:

5

By looking at the code of Collections class, i got to know that when we are using the method unmodifiableList(List list) or unmodifiableCollection(Collection c) it is not creating a new object but it is returning the reference of the same object and overriding the methods which can modify the List [ add, addall, remove, retainAll ... ]
So i ran this test:

List modifiableList = new ArrayList();
modifiableList.add ( 1 );   
List unmodifiableList = Collections.unmodifiableList( modifiableList );
// unmodifiableList.add(3);  // it will throw the exception 
modifiableList.add ( 2 );       
System.out.println( unmodifiableList );

result is [ 1,2 ] .
Now the point is why it is referring to the same object? Why it don't create a new object?

+3  A: 

Now the point is why it is referring to the same object? Why it don't create a new object?

Performance. It just doesn't scale to make a full copy. It would be a linear time operation to make a full copy which obviously isn't practical. Also, as others already noted, the point is that you can pass the reference of the unmodifiable list around without having to worry that it gets changed. This is very helpful for multithreaded programs.

Raoul Duke
+4  A: 

(answer of the queston at the bottom)

When you create an unmodifiable list, the purpose is that it should not be modified by people other than you - i.e. clients of an API.

the method unmodifiableList(..) creates a new object of type UnmodifiableList (but this is not a public class), which gets the original list, and delegates all methods to it except the methods which would modify it.

The point is, as stated in the documentation:

Returns an unmodifiable view of the specified list. This method allows modules to provide users with "read-only" access to internal lists.

So, an example: You have a List of devices that your API has detected and can operate, and you want to give them a client of your API. But he is not supposed to change them. So you have two options:

  • give him a deep copy of your List, so that even if he modifies it, this does not change your list
  • give him an unmodifiable collection - he can't modify it, and you spare the creation of a new collection.

And now here comes the answer to the title of your question - the unmodifiable list is a view of the original collection. So if you need to add a new item to it - say, you have discovered a new device that was just plugged-in, the clients will be able to see it in their unmodifiable view.

Bozho
Is this only for performance that we are getting the reference of the same List?
Rakesh Juyal
there is no performance involved here _directly_. It's only that you may want to disable modification of a List by clients of your API. See my update to see how performance is affected _indirectly_
Bozho
"it should not be modified" - I suggest you add ", not even elsewhere!"
Thorbjørn Ravn Andersen
+1  A: 

I believe the secret lies in implementation details... Collection.unmodifiableList() will simply give you decorated modifiable list. I mean unmodifiable list contains reference to modifiable list internally.

Paweł Dyda
+2  A: 

From documentation:

public static List unmodifiableList(List list)

Returns an unmodifiable view of the specified list. This method allows modules to provide users with "read-only" access to internal lists. Query operations on the returned list "read through" to the specified list, and attempts to modify the returned list, whether direct or via its iterator, result in an UnsupportedOperationException.

m01
A: 
  1. you should go for creating new Object of a list, only when the original Object is going to be changed and you need a backup , when someone corrupts it , u can replace by new Object.

  2. To create a ummodifiable object, i will wrap the original object and prevent add ,remove by throwing exception. but u know ,i can change each object present in the list .like if u have a person object in an umodifiable list , i can still change the name of the person object in the list.

Suresh S