Guava Immutable Collections vs Collections.unmodifiable
Java Collections
Collections.unmodifiableList or Collections.unmodifiableSet methods create a wrapper around the original list or set. Hence any changes to the original list would affect the unmodifiable list too.
Set<String> x = new HashSet<String>(); x.add("foo"); Set<String> builtIn = Collections.unmodifiableSet(x); x.add("bar"); System.out.println(builtIn.size()); // Prints 2
It would be more clear if you have a look at the implementation of Collections.unmodifiableList() method
public class Collections { public static <T> List<T> unmodifiableList(List<? extends T> list) { return (list instanceof RandomAccess ? new UnmodifiableRandomAccessList<T>(list) : new UnmodifiableList<T>(list)); } static class UnmodifiableList<E> extends UnmodifiableCollection<E> implements List<E> { static final long serialVersionUID = -283967356065247728L; final List<? extends E> list; UnmodifiableList(List<? extends E> list) { super(list); this.list = list; } public boolean equals(Object o) {return o == this || list.equals(o);} public int hashCode() {return list.hashCode();} public E get(int index) {return list.get(index);} public E set(int index, E element) { throw new UnsupportedOperationException(); } public void add(int index, E element) { throw new UnsupportedOperationException(); } public E remove(int index) { throw new UnsupportedOperationException(); } public int indexOf(Object o) {return list.indexOf(o);} public int lastIndexOf(Object o) {return list.lastIndexOf(o);} public boolean addAll(int index, Collection<? extends E> c) { throw new UnsupportedOperationException(); } ..... ..... } }
Have a look at the implementations of read methods like get(int index) or indexOf(Object o). They all just delegate the call to the underlying implementation of the original list.
Guava Immutable Collections
Guava creates a copy of the original list or set which is a more expensive computation and consumes more memory, but if someone alters the original list, it cant affect the ImmutableList.
Set<String> x = new HashSet<String>(); x.add("foo"); ImmutableSet<String> guava = ImmutableSet.copyOf(x); x.add("bar"); System.out.println(guava.size()); // Prints 1</pre>
In other words, ImmutableSet is immutable despite whatever collection it’s built from potentially changing – because it creates a copy. Note that this immutability is only applied to the collection and does not address the mutability of the objects you put in the Collection.
Some More Advantages Of ImmutableCollections
1. They are types and not implementations. An important difference between ImmutableSet and the Set created by Collections.unmodifiableSet is that ImmutableSet is a type. You can pass one around and have it remain clear that the set is immutable by using ImmutableSet rather than Set throughout the code. With Collections.unmodifiableSet, the returned type is just Set… so it’s only clear that the set is unmodifiable at the point where it is created unless you add Javadoc everywhere you pass that Set
saying “this set is unmodifiable”.
2. Order is preserved
3. Null values cannot be added
There are a few more mentioned here.
Posted on July 2, 2011, in guava, java and tagged collections, guava. Bookmark the permalink. Leave a comment.
Leave a comment
Comments 0