It should be noted that neither of the techniques advocated so far provide truly defensive copies.
Here's what unmodifiableMap does:
public V get(Object key) {
return m.get(key);
}
public V put(K key, V value) {
throw new UnsupportedOperationException();
}
It's really just a decorator class that prevents the altering of the internal Map reference(s), but it still allows access to the original objects, which means that someone (either the holder of the "unmodifiable map", or the holder of the original map) could get an object, and alter its contents.
Even creating a new Map or ArrayList and invoking the addAll method on the original objects doesn't solve this, because it only performs a "shallow copy". See
http://javatechniques.com/blog/faster-deep-copies-of-java-objects