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?
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.
This constructor creates a new list with all the items of the supplied Collection in the order returned by its iterator (see the documentation).
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.
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.
(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:
List
, so that even if he modifies it, this does not change your listAnd 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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With