HashMap
有一个返回entrySet()
Set<Map.Entry<K,V>>
该集由地图支持,因此对地图的更改将反映在中 集合,反之亦然
根据文档,我认为在HashMap
创建时,正在创建HashSet
,并且在HashMap
上执行任何操作时会更新它。
但是,我也知道HashSet
的{{3}}由HashMap
支持,其中键是唯一的,值是相同的单身。
所以EntrySet
不能在HashMap
的构造函数中创建,它需要是懒惰的吗?如果没有,new HashMap()
调用new HashSet()
再次调用new HashMap()
,直到堆爆炸。
感觉EntrySet
可以使用EntrySet.Key.hashCode()
和EntrySet.Key.equals()
进行哈希操作,这意味着HashMap
的{{1}}实现看起来与实际的EntrySet
非常相似,只是密钥的类型HashMap
与K
不同。那我们为什么要保留两份类似的副本呢?我们可以使用Map.Entry<K,V>
(一个EntrySet
)吗?
答案 0 :(得分:1)
根据文档,我认为在
HashMap
创建时,正在创建HashSet
,并且在HashMap
上执行任何操作时会更新它。
该文件并不意味着这样的事情。它只是指定集合的行为。
EntrySet
是
EntrySet
是一个内部类(非静态),因此它与其包含的类相关联 - HashMap
。返回后,对其进行的任何操作都将委托给地图,即entrySet.remove(o) { HashMap.this.remove(o); }
。EntrySet
将其表示为单个对列表。由于地图类似于矩阵结构,因此您可以考虑将其视为行列表或列列表。所以
EntrySet
不能在HashMap
的构造函数中创建,它需要是懒惰的吗?
它可以在HashMap
的构造中创建,但此时它是空的,所以没有多大意义。还不能保证它是必需的,因此没有理由创建它。
如果没有,
new HashMap()
调用new HashSet()
,再次调用新的HashMap()
,直到堆爆炸。
HashSet
没有参与。 EntrySet
和HashSet
都是AbstractSet
的直接子类。在任何情况下,为什么set构造函数会调用map构造函数?
感觉
EntrySet
可以使用EntrySet.Key.hashCode()
和EntrySet.Key.equals()
进行哈希操作......
EntrySet
不需要自行哈希,它使用HashMap
的{{1}}方法。
...这意味着
hash()
的实施中的HashMap
看起来非常类似于实际EntrySet
...
HashMap
的实现没有保留EntrySet
的副本,它与它的内部类相关联。
...除了密钥的类型
HashMap
与K
不同。
Map.Entry<K,V>
中的密钥类型与EntrySet<K, V>
中的密钥类型相同。
那为什么我们要保留两份相似的副本?我们可以使用
HashMap<K, V>
(一个EntrySet
)吗?
见上文,没有副本。
我引用您HashMap
的{{3}},但您可以更轻松地在IDE中进行检查。