/**
* Returns the empty map (immutable). This map is serializable.
*
* <p>This example illustrates the type-safe way to obtain an empty set:
* <pre>
* Map<String, Date> 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;
}
上面的函数返回一个不可变的空映射。
public static final Map EMPTY_MAP = new EmptyMap<>();
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;
}
}
这种类和实用方法有什么用?我试过了
Map myMap = Collections.emptyMap();
myMap.put("Name","John");
我得Exception in thread "main" java.lang.UnsupportedOperationException
因为不可变的集合不支持修改。那么这种数据结构的用途是什么?
答案 0 :(得分:13)
这种类和实用方法的用途是什么?
如果你要返回一个Map
结果,那么它通常是有用的......例如,你可以创建一个包含你自己的“真实”数据的不可变映射,而不是必须创建完整副本,或信任调用者不要改变它。
另外,如果你要返回一个空的Map
结果,那么每次都不必创建一个新对象 - 每个空地图都等同于其他每个空地图,所以使用起来很好单个实例。
答案 1 :(得分:7)
这有助于实现Null对象设计模式http://en.wikipedia.org/wiki/Null_Object_pattern,即返回空映射而不是null
答案 2 :(得分:4)
对于您的情况,我想对不可变Collections.EMPTY_MAP
的最佳解释如下:
该字段被声明为公共字段(以便于访问)。如果你没有做到最终,这意味着你可以随时来,并有一些像这样的代码:
//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
这对你来说非常糟糕,因为你可能会发现你的程序行为是错误的。
如果您阅读Effective Java 2nd edition第43项(返回空数组或集合,而不是空值),建议返回一个空集合,这样您就不必在开发时包含空数组操作代码。您也可以将其称为Null-Object-Pattern。
好的,那么与不可变的EMPTY_COLLECTION(或你的情况下的MAP)有什么关系呢? 想象一下,您将在类中使用许多方法,并调用一个方法,该方法从一个集合中生成一组元素,并返回这些组的集合,除非(此处插入随机条件)。
到目前为止一切顺利。假设您决定使用EMPTY_MAP
中的Collections
(如果它在那里,为什么不呢?)。您在几个地方返回空地图,但在其中一些地方您想要修改它。您将引用EMPTY_MAP修改为使用此引用的所有代码(这会将我们带回到数字1.请记住EMPTY_MAP中的更改?)。
这个原因如果用于减少内存和类似的东西。如果它不是不可变的,你每次想要一个空地图就会创建新实例,这会导致你(你可以说是严重的)内存(不是泄漏,但是)性能(我不太清楚这个术语,但是你明白了。也许你听说过singleton,这是一回事。
你去吧。这是您需要不可变EMPTY_MAP的主要原因(我现在可以想到)。
对于您的问题的解决方案,您不应该使用EMPTY_MAP,您应该自己创建一个。这并不难,你摆脱了这些讨厌(可怕)不可改变的事情。
祝你好运!
答案 3 :(得分:1)
这个堆栈溢出问题可能会有所帮助:使用不可变空集(Collections.emptyMap() vs new HashMap())
答案 4 :(得分:0)
它(与空List和空Set一起使用)返回一个空集合,而不需要每次都实例化一个新对象。