Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can we change the unmodifiable list if we have the original one?

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?

like image 450
Rakesh Juyal Avatar asked Sep 06 '10 10:09

Rakesh Juyal


People also ask

How do you make an unmodifiable list modifiable?

The solution to this problem is quite simple and is highlighted in the following code. final List<String> modifiable = new ArrayList<>(); modifiable. add("Java"); modifiable. add("is"); // Here we are creating a new array list final List<String> unmodifiable = Collections.

Does unmodifiableList create a new list?

This constructor creates a new list with all the items of the supplied Collection in the order returned by its iterator (see the documentation).

Is Unmodifiable list immutable?

A collection is considered unmodifiable if elements cannot be added, removed, or replaced. However, an unmodifiable collection is only immutable if the elements contained in the collection are immutable.

What is an unmodifiable list?

The Iterator of elements provides the order of the elements. An unmodifiable list cannot have its length or elements changed. If the elements are themselves immutable, then the resulting list is also immutable.


3 Answers

(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.

like image 141
Bozho Avatar answered Oct 19 '22 07:10

Bozho


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.

like image 41
Raoul Duke Avatar answered Oct 19 '22 07:10

Raoul Duke


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.

like image 30
mik01aj Avatar answered Oct 19 '22 06:10

mik01aj