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.

Advertisement

Posted on July 2, 2011, in guava, java and tagged , . Bookmark the permalink. Leave a comment.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: