1

The Java Collection framework provides an elegant solution to create an unmodifiable Collection like Lists, Sets, Maps from an existing one.

Sounds too good. Will it serve our purpose? One day was debugging an issue about mutable objects and unmodifiable list. Got a very peculiar behavior.

Lets consider below code snippet.

 public class UnmodifibleList {
 public static void main(String[] args) {
    String s1=    "Good";  
    String s2=   "Morning";  
    final List modifiableList = new ArrayList();
    modifiableList.add(s1);  
    modifiableList.add(s2);  
    final List unmodifiableList = Collections.unmodifiableList(modifiableList);
    System.out.println("Before modifying: " + unmodifiableList );
    modifiableList .add("nice");
    modifiableList .add("day"); 
    System.out.println("After modifying: " + unmodifiableList);
  }
}

And the Output as follows:

Before modifying: [Good, Morning]
After modifying: [Good, Morning, nice, day]

Is it seems strange? Unmodifiable list gets modified after the method call Collections.unmodifiableList()

What the java doc says:

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. The returned list will be serializable if the specified list is serializable. Similarly, the returned list will implement RandomAccess if the specified list does.

Parameters: list the list for which an unmodifiable view is to be returned. Returns: an unmodifiable view of the specified list.

But it does not say if we modify the underlying collection the returned unmodifiable list will also be modified.

Can some suggest me this behaviour.

No Exact solution is found there in linked question , how ever i have implemented my own,

 public class UnmodifibleList {
public static void main(String[] args) {
    String s1=    "Good";  
    String s2=   "Morning";  
    final List modifiableList = new ArrayList();
    modifiableList.add(s1);  
    modifiableList.add(s2);  
    final List unmodifiableList =      Collections.unmodifiableList(new ArrayList(modifiableList));
    System.out.println("Before modifying: " + unmodifiableList );
    modifiableList .add("nice");
    modifiableList .add("day");  
    System.out.println("After modifying: " + unmodifiableList);
    }
 } 

Please look at the line in the above code where we are calling Collections.unmodifiableList().Here we are creating a brand new ArrayList and passing the original list inside it.

Before modification: [Good, Morning]
After modification: [bad, Morning]
Ashish Kakkad
  • 23,586
  • 12
  • 103
  • 136
T-Bag
  • 10,916
  • 3
  • 54
  • 118
  • 1
    You aren't trying to add to the collection of `unmodifiableList`. You continue to manipulate `modifiableList`, which is not of `Collections.unmodifiableList`. – Sean Perkins Dec 14 '15 at 05:40
  • But as doc says you can pass the list to Collections.unmodifiableList constructor to make it un-modifiable – T-Bag Dec 14 '15 at 05:42
  • 1
    @ShowStopper No, you are making a view of the list, which the view is read-only. If you apply logic to the original collection, the view is never called. – Sean Perkins Dec 14 '15 at 05:44
  • 1
    An `UnmodifiableList` is a view, changes made to the original List will be reflected in it. That's why it is suggested to re-assign the refrence to the original. – TheLostMind Dec 14 '15 at 05:46
  • You need to re-assign the returned reference like this : `List l1 = new ArrayList<>(); l1 = Collections.unmodifiableList(l1);` – TheLostMind Dec 14 '15 at 05:51
  • Dont mark duplicate until you have valid POC with great power there comes great responsibility as well. – T-Bag Dec 14 '15 at 05:51
  • 1
    @ShowStopper - Check *z5h*'s answer to that question. **Using Collections.unmodifiableList creates a wrapper around your List. if the underlying list changes, so does your unmodifiableList's view.**. I marked it as a dup after giving it a thought. I have watched spiderman movies as well :) – TheLostMind Dec 14 '15 at 05:53
  • Just kidding bro thanks... :) – T-Bag Dec 14 '15 at 06:32

0 Answers0