1)mutable(它的方法setValue(
)改变条目的值部分
2)定义了equals()
/ hashCode()
,包括条目的值部分
3)成为Set<Map.Entry<T,K>> entrySet()
结果
在我看来,这三点是有争议的。例如,前两个违反Set<>
接口的合同,该接口不建议使用该集合中的可变元素。
我可以肯定,Value
的变异不会破坏地图吗?
为什么他们没有Entry
只能按密钥进行比较和清除?这会在某些情况下提高速度吗?
答案 0 :(得分:5)
我确定,Value的变异不会破坏地图吗?
是的,绝对的。 HashMap
存储桶仅考虑条目的关键部分:
public V [More ...] put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode()); // <<== HERE
...
}
为什么他们没有进入可比较且只能按键加密?这会在某些情况下提高速度吗?
hashCode
的{{1}}和equals
几乎没有相关性:只有当你想在外 {{1}本身。提供给Map.Entry
的呼叫者的HashMap
的内部实现不使用条目的EntrySet
/ Map.entrySet
- 而是使用仅密钥部分的哈希码。以下是在条目集中查找对象的相关源代码的一部分:
hashCode
答案 1 :(得分:0)
这可能是一个&#34;意见&#34;题。这是我最好的猜测。
我认为Set<Map.Entry<T,K>>
可用,因此您可以迭代集合的元素以获取地图中的所有键/值对。但是,很少会使用此Set
上的其他操作。特别是,似乎不太可能在这个集合上使用contains
方法,这需要构建一个具有键和的具体类的Map.Entry
对象。价值,看看它是否在Set<Map.Entry<T,K>>
中。由于我认为contains
将是hashCode
的主要用途,并且由于很少会使用contains
,因此我不认为为hashCode()
定义{ {1}}有很大用处,因此它不应引起关注。当然,Map.Entry
存在,因为所有hashCode()
都有它们;为什么他们觉得有必要正式定义其价值,我不知道。但我认为这是无害的。
答案 2 :(得分:0)
这里没有矛盾。您似乎错过的要点是entrySet()
不支持向其添加元素。
因此,如果一个集合在地图返回时格式良好,那么
Entry
的哈希码,但不能影响密钥的哈希码,因此HashMaps不会中断 - 桶的条目仍然相同Entry
的位置。 实际上:setValue()
不允许您更改关于地图如何处理条目的任何内容,因此将保留所有地图合约。
我无法证明为什么equals()
和hashCode()
以这种特定的方式实现,也许Java的作者有一个用例,我不知道。 (然后我再也没有考虑过这些方法的任何用例)
答案 3 :(得分:0)
AbstractMap.SimpleEntry的实现被认为是一个私有实现细节(它甚至不被所有Map实现使用,例如HashMap不使用它)。
请注意,没有API 直接公开此类型 - 可以说这个类可能已被保护或包私有而不是公共。
定义的公共API是Map.Entry(请注意,任何Map都返回一个Set)。 Entry的任何实现都需要符合此契约,并且在那里明确定义了hashCode实现。
使用SimpleEntry的类需要覆盖定义的一部分来处理其entrySet()实现所需的setValue() if (看看HashMap的一个例子如何处理)。注册的hashCode,虽然已经记录,但是通过entrySet()的实现并不是必然使用。
至于&#34;为什么&#34;它是这样的:询问设计师。我猜想的是,没有更深层次的原因。