了解Map get方法

时间:2015-11-23 08:02:49

标签: java dictionary

阅读Map#get(Object key)的JavaDocs我并不完全明白返回的方法究竟是什么。 The quote

  

返回指定键映射到的值,或null if   此地图不包含密钥的映射。

他们是什么意思返回值?它可能是作为映射对象的副本创建的新对象吗?我想了下面这个简单的程序:

public static void main (String[] args) throws java.lang.Exception
{
    Map<Integer, MyClass> m = new HashMap<>();
    m.put(1, new MyClass());
    MyClass mc = m.get(1);
    mc.i = 15;
    System.out.println(m.get(1).i); //prints 15
}

private static class MyClass{
    public int i = 10;
}

DEMO

通过更改get(Object key)返回的对象的状态是否可靠,我更改了实际的映射对象,或者它是特定于实现的,Map的任意实现不应该保留它?

3 个答案:

答案 0 :(得分:3)

简短的回答,是的。

地图保留对添加到其中的对象的引用。因此,当您调用get时,您将获得对原始对象的引用,并且所做的任何更改都是有效的。

文档状态[1]: 注意:如果将可变对象用作映射键,则必须非常小心。如果在对象是地图中的键的情况下以影响等于比较的方式更改对象的值,则不指定映射的行为。这种禁令的一个特例是地图不允许将自己作为关键词包含在内。虽然允许地图将自身包含为值,但建议极其谨慎:在这样的地图上不再定义equals和hashCode方法。

因此,即使他们注意到您可以更改映射对象,但在更改影响等于返回值的字段时,如果将其用作键,则应记住某些事项。

[1] http://docs.oracle.com/javase/7/docs/api/java/util/Map.html

答案 1 :(得分:1)

Map的作用是将键与对象引用相关联,因此每当使用get方法检索对象时,实际上都会检索对象的引用。因此,每当您使用此引用执行任何操作时,您都会操纵实际对象。

答案 2 :(得分:1)

我认为在使用像“价值”这样的重载术语时可能存在一些混淆。这不是“价值传递”中的“价值”,而是Map's Javadoc的第一句意义:

  

[地图是]将键映射到值

的对象

该值只是为给定密钥存储的实例。

所以以下情况应该是真的:

K key = getTheKey();
V value = getTheValue();

Map<K, V> map = new HashMap<>();
map.put(key, value);
assert value == map.get(key);  // The call to get returns the same instance that you put into the map.

当你调用get时,不能复制实例 - 在一般情况下,不知道如何创建对象的副本。