[英]How can AbstractMap.SimpleEntry be mutable?
How can AbstractMap.SimpleEntry
be simultaneously 如何同时
AbstractMap.SimpleEntry
1) mutable (it's method setValue(
) changes value part of the entry) 1)可变的(它的方法
setValue(
)更改条目的值部分)
2) having equals()
/ hashCode()
defined including value part of the entry 2)具有
equals()
/ hashCode()
定义,包括条目的值部分
3) be the part of Set<Map.Entry<T,K>> entrySet()
result 3)是
Set<Map.Entry<T,K>> entrySet()
结果的一部分
It seems to me, that these three points are controversial. 在我看来,这三点是有争议的。 For example, first two violates contract of
Set<>
interface, which is not recommending to have mutable elements of the set. 例如,前两个违反了
Set<>
接口的协定,这不建议使用set的可变元素。
May I be sure, that mutating of Value
won't break the map? 我可以确定,
Value
变化不会破坏地图吗?
Why didn't they did Entry
comparable and hashable by key only? 他们为什么不让
Entry
只能通过键进行比较和散列? This would increase speed in some cases? 在某些情况下会提高速度?
I be sure, that mutating of Value won't break the map?
我敢肯定,价值的变化不会破坏地图吗?
Yes, absolutely. 是的,一点没错。 The
HashMap
buckets take into account only the key portion of the entry: HashMap
存储桶仅考虑条目的关键部分:
public V [More ...] put(K key, V value) {
if (key == null)
return putForNullKey(value);
int hash = hash(key.hashCode()); // <<== HERE
...
}
Why didn't they did Entry comparable and hashable by key only?
他们为什么不让Entry只能通过键进行比较和散列? This would increase speed in some cases?
在某些情况下会提高速度?
The hashCode
and equals
of Map.Entry
have very little relevance: they would be used only if you wanted to hash entries outside the HashMap
itself. Map.Entry
的hashCode
和equals
的相关性很小:仅当您想对HashMap
本身之外的条目进行哈希处理时,才使用它们。 The internal implementation of the EntrySet
supplied to the callers of Map.entrySet
does not use hashCode
/ equals
of the entry - instead, they use the hash code of only the key portion. 提供给
Map.entrySet
调用者的EntrySet
的内部实现不使用hashCode
/ equals
条目-而是仅使用关键部分的哈希码。 Here is part of a relevant source code for looking up an object in the entry set: 这是用于在条目集中查找对象的相关源代码的一部分:
public boolean contains(Object o) {
if (!(o instanceof Map.Entry))
return false;
Map.Entry<K,V> e = (Map.Entry<K,V>) o;
Entry<K,V> candidate = getEntry(e.getKey());
return candidate != null && candidate.equals(e);
}
This might be an "opinion" question. 这可能是一个“观点”问题。 Here's my best guess.
这是我最好的猜测。
I think that Set<Map.Entry<T,K>>
is made available so that you can iterate over the elements of the set to get all key/value pairs in a map. 我认为可以使用
Set<Map.Entry<T,K>>
以便您可以迭代集合的元素以获取映射中的所有键/值对。 However, other operations on this Set
would be used rarely. 但是,很少使用此
Set
上的其他操作。 In particular, it seems unlikely that one would use the contains
method on this set, which would require building a Map.Entry
object of some concrete class that has both a key and a value, to see if it's in this Set<Map.Entry<T,K>>
. 特别是,似乎不太可能在此集合上使用
contains
方法,这需要构建具有键和值的某个具体类的Map.Entry
对象,以查看它是否在此Set<Map.Entry<T,K>>
。 Since I think contains
would be the main use of the hashCode
, and since contains
would rarely be used, I don't think the hashCode()
defined for the Map.Entry
is of much use, and thus it shouldn't be a cause for concern. 由于我认为
contains
将是hashCode
的主要用途,并且由于contains
将很少被使用,因此我认为为Map.Entry
定义的hashCode()
不会有太大用处,因此它不应成为原因值得关注。 hashCode()
is, of course, present because all Object
s have them; hashCode()
之所以存在,是因为所有Object
都有它们; why they felt a need to define its value formally, I don't know. 他们不知道为什么他们需要正式定义其价值。 But I think it's harmless.
但是我认为这是无害的。
There is no contradiction here. 这里没有矛盾。 The main point that you seem to have missed is that
entrySet()
does not support adding elements to it . 您似乎错过的要点是
entrySet()
不支持向其中添加元素 。
As such, if a set is well-formed when it is returned by the map, you 这样一来,如果地图返回时集合格式正确,则您
Entry
, but cannot influence the hash code of the key, so HashMaps will not break - the bucket of the entry is still the same Entry
的哈希码,但不能影响键的哈希码,因此HashMaps不会中断-条目的存储桶仍然相同 Entry
in a sorted map. Entry
在已排序地图中的位置。 In fact: setValue()
does not allow you to change ANYTHING about how the entry is handled by the map, and hence all map contracts will be preserved. 实际上:
setValue()
不允许您更改有关地图如何处理条目的任何内容,因此将保留所有地图协定。
I cannot attest why exactly equals()
and hashCode()
were implemented in this specific way, maybe the authors of Java had a use case in mind, I don't. 我无法证明为什么完全以这种特定方式实现了
equals()
和hashCode()
,也许Java的作者想到了用例,但我没有。 (Then again I don't have any use case for those methods in mind at all) (然后我再也不用考虑这些方法的用例了)
The implementation of AbstractMap.SimpleEntry is to be considered a private implementation detail (its not even used by all Map implementations, eg HashMap doesn't use it). AbstractMap.SimpleEntry的实现应被视为私有的实现细节(它甚至没有被所有Map实现使用,例如HashMap不使用它)。
Note that there is no API that exposes this type directly - its arguable that this class could have been made protected or package private instead of public. 请注意, 没有API可以直接公开此类型-可以争论此类可能已被保护或打包为私有而不是公共。
The defining public API is Map.Entry (note that any Map returns a Set). 定义的公共API是Map.Entry(请注意,任何Map都会返回Set)。 Any implementation of Entry needs to conform to this contract, and the hashCode implementation is clearly defined there.
Entry的任何实现都需要遵守此合同,并且在那里明确定义了hashCode实现。
A class making use of SimpleEntry will need to override part of the definition to handle setValue() if that is needed by its entrySet() implementation (Take a look at HashMap for an example how its handled). 一类利用SimpleEntry将需要重写定义的一部分来处理的setValue() 如果这是由它的entrySet()实现需要(看看HashMap的一个例子,如何处理它)。 The hashCode of Entry, while documented, is not neccessarily used by the implementation of entrySet().
虽然有记录, 但 EntrySet()的实现不必使用 Entry的hashCode。
As for "why" is it the way it is: Ask the designer. 至于“为什么”是这样的:请设计师。 Conjecture on my part is that there isn't a deeper reason.
我的猜测是,没有更深层次的原因。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.