假设您有以下代码:
Map<Foo, Bar> map = new HashMap<Foo, Bar>();
Foo foo = new Foo();
Bar bar = new Bar();
map.put(foo, bar);
Bar barReturned = map.get(foo);
Java需要那个barReturned == bar
吗?也就是说,Java是否要求barReturned
与bar
是同一个实例?如果没有,那么需要什么样的语义?
Javadoc建议barReturned == bar
必须是真的,但我不能百分之百肯定:
V get(Object key)
返回指定键映射到的值,如果此映射不包含键的映射,则返回null
。 更正式地说,如果此映射包含从键k
到值v
的映射(如(key==null ? k==null : key.equals(k))
),则此方法返回v
;否则将返回null
。(最多只能有一个这样的映射。) 如果此映射允许null
值,则返回值null并不一定表示映射不包含对键的映射;映射也可能显式地将键映射到null
。containsKey手术可以用来区分这两种情况。 参数:key
-该键的关联值将被返回 返回: 指定键映射到的值,如果此映射不包含键的映射,则为或null
。
(强调地雷)
编辑:--我理解与标准库捆绑在一起的Map
实现遵循barReturned == bar
语义。我想知道的是,根据文档,这种行为是否是必需的。例如,如果我编写实现Map
的类,那么必须遵守这些语义吗?
发布于 2011-02-17 04:54:26
如果你问你是否能打破这种关系,我认为答案是“是”。例如,如果您正在实现一个像持久缓存一样的Map,那么如果没有在一段时间内使用,那么可能会将一个特定的值写入磁盘,然后稍后重新加载。在这种情况下,你不会有引用相等,但没关系。显然,您需要记录任何偏离标准行为的情况,但我不认为这超出了Map的合理使用范围。
发布于 2011-02-17 04:46:03
当然,它将是--同一个实例。否则Map
就没用了。
不过,这方面的唯一例外是多线程应用程序,在调用put
和get
之间,其他线程可以将任意值放入相同的键。
正如亚当在评论中指出的那样,编辑有一个特殊的情况,他的地图实现可以重新创建传入的对象并使用它们的副本。从这个意义上说,original.equals(copy)
是真,original == copy
是假。在这种情况下,我认为Map可以存储副本而不是原件。
发布于 2011-02-17 04:50:37
如果您将javadocs中使用的术语值解释为映射中对象的引用,这将意味着您始终需要返回与您在映射中放置的引用相同的引用,并且您将具有==相等。然后,更多的问题是文档中使用的值一词的定义。
https://stackoverflow.com/questions/5028962
复制相似问题