10
/**
 * Returns the empty map (immutable).  This map is serializable.
 *
 * <p>This example illustrates the type-safe way to obtain an empty set:
 * <pre>
 *     Map&lt;String, Date&gt; s = Collections.emptyMap();
 * </pre>
 * Implementation note:  Implementations of this method need not
 * create a separate <tt>Map</tt> object for each call.   Using this
 * method is likely to have comparable cost to using the like-named
 * field.  (Unlike this method, the field does not provide type safety.)
 *
 * @see #EMPTY_MAP
 * @since 1.5
 */
@SuppressWarnings("unchecked")
public static final <K,V> Map<K,V> emptyMap() {
    return (Map<K,V>) EMPTY_MAP;
}

Above function returns an immutable empty map.

public static final Map EMPTY_MAP = new EmptyMap<>();

EmptyMap class is as follows

/**
 * @serial include
 */
private static class EmptyMap<K,V>
    extends AbstractMap<K,V>
    implements Serializable
{
    private static final long serialVersionUID = 6428348081105594320L;

    public int size()                          {return 0;}
    public boolean isEmpty()                   {return true;}
    public boolean containsKey(Object key)     {return false;}
    public boolean containsValue(Object value) {return false;}
    public V get(Object key)                   {return null;}
    public Set<K> keySet()                     {return emptySet();}
    public Collection<V> values()              {return emptySet();}
    public Set<Map.Entry<K,V>> entrySet()      {return emptySet();}

    public boolean equals(Object o) {
        return (o instanceof Map) && ((Map<?,?>)o).isEmpty();
    }

    public int hashCode()                      {return 0;}

    // Preserves singleton property
    private Object readResolve() {
        return EMPTY_MAP;
    }
}

What is the use of such Class and utility method? I tried

Map myMap = Collections.emptyMap();
myMap.put("Name","John");

and I get Exception in thread "main" java.lang.UnsupportedOperationException because collection being immutable does not support modification. So whats the use of such data structure?

Aniket Thakur
  • 66,731
  • 38
  • 279
  • 289
  • 3
    I am not sure..but my guess is this is helpful in something like a null object pattern. Instead of returning a null reference from a method you can return a empty map. – Asha Aug 02 '13 at 08:47
  • possible duplicate of [Collections.emptyMap() vs new HashMap()](http://stackoverflow.com/questions/14846920/collections-emptymap-vs-new-hashmap) – assylias Aug 02 '13 at 08:59

5 Answers5

15

What is the use of such Class and utility method?

If you're returning a Map result, it's often useful for it to be immutable... for example, you can create an immutable map which wraps your own "real" data rather than having to either create a full copy, or trust the caller not to mutate it.

Also, if you're returning a Map result which is empty, it's convenient not to have to create a new object each time - every empty map is equivalent to every other empty map, so it's fine to use a single instance.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
6

This helps to implement Null Object design pattern http://en.wikipedia.org/wiki/Null_Object_pattern, that is returning an empty map instead of null

Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
4

For your case, I guess the best explanation for immutable Collections.EMPTY_MAP is the following:

  1. The field is declared as public (for ease of access). If you don't make it final, this means you can come at any time and have a little code like this:

    //somewhere in your program (or someone else's)
    Collections.EMPTY_MAP = new EmptyMap<"String","String">("unwantedKey","unwantedValue");
    
    //what do you actually want to do
    Map myMap = Collections.emptyMap();
    //you would expect an empty map, but you will get something else
    

    this will be very bad for you as you can probably see that you're program behaviour will be wrong.

  2. If you read Effective Java 2nd edition item 43 (Return empty arrays or collections, not nulls) it is recommended to return an empty Collection, so you wont have to include null-array manipulation code when developing. You may refer to this as Null-Object-Pattern as well.

    OK, so what have that to do with immutable EMPTY_COLLECTION (or MAP in your case)? Imagine that you would use many methods in your class, and you call a method that makes groups of elements from a collection, and returns a collection of the groups, unless (random condition inserted here).

    So far so good. Let's say that you decide to use the EMPTY_MAP from Collections (if it's there, why not?). You return the empty map in several places, but in some of them you want to modify it. You modify the reference EMPTY_MAP to all of your code that uses this reference (This brings us back to number 1. Remember the change in EMPTY_MAP?).

  3. This reason if for memory reduction and stuff like that. If it wouldn't be immutable and you would create new instances every time you wanted an empty map, that would cause you (you could say severe) memory (not leaks, but) performance (I don't quite know the term, but you get the idea). Maybe you heard of singleton, this is the same thing.

There you go. This are the main 3 reasons (that i can think of at the moment) for what you need immutable EMPTY_MAP.

And a solution to your problem, you shouldn't use EMPTY_MAP, you should create one yourself. It's not that hard, and you get rid of these nasty (scary) immutable things.

Good Luck!

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
1

This stack overflow question might help : use of immutable empty set(Collections.emptyMap() vs new HashMap())

Community
  • 1
  • 1
r3ap3r
  • 2,775
  • 2
  • 17
  • 16
1

It's used (together with emptyList and emptySet) to return an empty colletion without the need to instantiate a new object everytime.

growlingchaos
  • 96
  • 2
  • 8