我想知道让Java的Map.put(key, value)
方法覆盖已经在集合中的等价键值的原因是什么,而Set.add(value)
不会覆盖已经存在的等价值在集合中?
看起来多数人的观点是,评估为相等的集合中的对象在每个方面都应该相等,因此如果Set.add(Object)覆盖等价的对象则无关紧要。如果两个对象评估为相等,但实际上确实包含不同的数据,那么Map类型集合是更合适的容器。
我有点不同意这个观点 示例:包含一组“Person”对象的集合。为了更新有关该人员的某些信息,您可能希望传递该集合一个新的,更新的人员对象来覆盖旧的,过时的人员对象。在这种情况下,Person将持有一个主键,用于标识该个人,并且该集合将仅基于其主键来识别和比较人员。这个主键是人的身份的一部分,而不是外部参考,如地图意味着。
答案 0 :(得分:9)
Map
行为允许更改与等效键关联的值。这是一个非常常见的用例:a : b
变为a : c
。
是的,用Set
覆盖add
内容可能会改变某些内容(参考值) - 但这似乎是一个非常狭窄的用例(无论如何都可以完成 - 总是在添加之前尝试删除:s.remove(o); s.add(o);
)相对于大多数情况下的情况 - 没有任何循环。
编辑:
我可以看到这种行为的一个潜在用途,就是有一个受限的内存预算,创建了大量重等但是等价的对象,并且在不同的地方引用了不同的相同版本,防止了重复版本的垃圾收集。然而,在遇到这个问题之前,我认为这种行为甚至不是解决它的最好方法。
答案 1 :(得分:5)
在我看来,在Set中覆盖一些东西是没有意义的,因为什么都不会改变。
但是,更新地图时,密钥可能相同,但值可能不同。
答案 2 :(得分:1)
请注意,Map实际上并没有那么不同......它可能总是更改值,但是(至少在Sun的实现中)即使稍后调用put()使用不同的实例进行比较,密钥也将保持不变等于原来的。
答案 3 :(得分:0)
我不同意你的问题的前提。 Map和Set都是抽象接口。它们是否覆盖是一个实现细节。