public class TestImmutableCollection {
static class Helper {
int val;
public Helper(int val) {
this.val = val;
}
@Override
public String toString() {
return String.valueOf(val);
}
}
public static void main(String[] args) {
List<Helper> origin = new ArrayList<>();
origin.add(new Helper(10));
origin.add(new Helper(11));
origin.add(new Helper(13));
ImmutableList<Helper> ul = ImmutableList.copyOf(origin);
ul.get(0).val = 15;
System.out.println(ul);
System.out.println(origin);
}
}
I was asked about immutability in a previous interview thus I search the Internet on Immutable Collections in Java. So I ran into this post Java Immutable Collections where quite a few people referenced that Guava has a better and safer implementation of the Immutable Collections. Before using guava I have already tested the above code using JDK's built-in UnmodifiableList which turned out the UnmodifiableList is just a wrapper of the original list so that the content of both list will be updated if I use get to access the inner element and then update the field of the element object.
As people stated in the previous post:
Unlike Collections.unmodifiableList(java.util.List<? extends T>), which is a view of a separate collection that can still change, an instance of ImmutableList contains its own private data and will never change.
Then I test the code with guava ImmutableList. But still it gave the same result. Both the content of the ImmutableList created by copyOf()
and the original list has changed.
I am quite confused why turns out like that. Am I understanding the scope of immutability here? The change of content of the elements in the Collection won't be judge as a change to the Collection here? But the doc of guava says so absolutely that it will never change.
If so, what is the difference between guava ImmutableList and JDK's UnmodifiableList in this case?
Hope someone can draw a light on that. Appreciate that.
Updated: Well, I know it is not a good design not to add any access constraint on fields of a class. But just try to image a realistic case where the Helper can be like an Account of a user, the filed can be the user's username, you will certainly provide a method to update this username field , right? Then in this case how can I just show the info of the accounts in the list without letting the caller to modify the content of the element in this list?