首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >当通过Map.put(K,V)添加值时,必须通过Map.get(K)返回相同的实例吗?

当通过Map.put(K,V)添加值时,必须通过Map.get(K)返回相同的实例吗?
EN

Stack Overflow用户
提问于 2011-02-17 12:33:35
回答 7查看 562关注 0票数 5

假设您有以下代码:

代码语言:javascript
代码运行次数:0
运行
复制
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是否要求barReturnedbar是同一个实例?如果没有,那么需要什么样的语义?

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的类,那么必须遵守这些语义吗?

EN

回答 7

Stack Overflow用户

发布于 2011-02-17 12:54:26

如果你问你是否能打破这种关系,我认为答案是“是”。例如,如果您正在实现一个像持久缓存一样的Map,那么如果没有在一段时间内使用,那么可能会将一个特定的值写入磁盘,然后稍后重新加载。在这种情况下,你不会有引用相等,但没关系。显然,您需要记录任何偏离标准行为的情况,但我不认为这超出了Map的合理使用范围。

票数 4
EN

Stack Overflow用户

发布于 2011-02-17 12:46:03

当然,它将是--同一个实例。否则Map就没用了。

不过,这方面的唯一例外是多线程应用程序,在调用putget之间,其他线程可以将任意值放入相同的键。

正如亚当在评论中指出的那样,编辑有一个特殊的情况,他的地图实现可以重新创建传入的对象并使用它们的副本。从这个意义上说,original.equals(copy)是真,original == copy是假。在这种情况下,我认为Map可以存储副本而不是原件。

票数 1
EN

Stack Overflow用户

发布于 2011-02-17 12:50:37

如果您将javadocs中使用的术语解释为映射中对象的引用,这将意味着您始终需要返回与您在映射中放置的引用相同的引用,并且您将具有==相等。然后,更多的问题是文档中使用的值一词的定义。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5028962

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档