为什么我们有不可变的空地图?

Ani*_*kur 9 java collections map immutability

/**
 * 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;
}
Run Code Online (Sandbox Code Playgroud)

上面的函数返回一个不可变的空映射.

public static final Map EMPTY_MAP = new EmptyMap<>();
Run Code Online (Sandbox Code Playgroud)

EmptyMap类如下

/**
 * @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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这种类和实用方法有什么用?我试过了

Map myMap = Collections.emptyMap();
myMap.put("Name","John");
Run Code Online (Sandbox Code Playgroud)

我得到Exception in thread "main" java.lang.UnsupportedOperationException 因为收集不可变不支持修改.那么这种数据结构的用途是什么?

Jon*_*eet 14

这种类和实用方法有什么用?

如果你要返回一个Map结果,它通常是有用的,因为它是不可变的...例如,你可以创建一个不可变的映射,它包装你自己的"真实"数据,而不是必须创建一个完整的副本,或信任调用者不要改变它.

另外,如果你返回一个Map空的结果,那么每次都不必创建一个新对象 - 每个空映射都等同于每个其他空映射,因此使用单个实例是很好的.


Evg*_*eev 7

这有助于实现Null对象设计模式http://en.wikipedia.org/wiki/Null_Object_pattern,即返回空映射而不是null