[英]How do HashMap.values() and HashMap.keySet() return values and keys?
The source code of HashMap.values()
is shown as follows HashMap.values()
的源代码如下所示
public Collection<V> values() {
Collection<V> vs = values;
return (vs != null ? vs : (values = new Values()));
}
As you can see, when the values()
method first called, it just returns a Values
object. 如您所见,当values()
方法首次调用时,它只返回一个Values
对象。 The Values
object is a subclass of AbstractCollection
with no constructor, and of course contains no element. Values
对象是AbstractCollection
的子类,没有构造函数,当然不包含任何元素。 But when I called the method, it returned a collection rapidly 但是当我调用该方法时,它会快速返回一个集合
Collection<String> values = map.values();
System.out.println(values);
That's so weird. 那太奇怪了。 Not only values()
, but also keySet()
and entrySet()
method return such empty objects. 不仅values()
,而且keySet()
和entrySet()
方法返回这样的空对象。 So, here is my question, when and how do these methods return objects with elements we need? 那么,这是我的问题,这些方法何时以及如何返回具有我们需要的元素的对象?
It's a misconception that the Values
class is "of course empty". 错误的观点是, Values
类“当然是空的”。 Just because there is no method called on it and its constructor doesn't have any arguments doesn't mean that the collection is empty. 只是因为没有调用它的方法并且它的构造函数没有任何参数并不意味着该集合是空的。
The Values
class is an "inner class" (a non-static nested class ) of HashMap
, which means that it has an implicit reference to the HashMap
object that created it. Values
类是HashMap
的“内部类”(非静态嵌套类 ),这意味着它具有对创建它的HashMap
对象的隐式引用。 It can therefore access all elements of the HashMap
, either explicitly by using the HashMap.this
reference or by just accessing the members directly. 因此,它可以通过使用HashMap.this
引用或直接访问成员来显式访问HashMap
所有元素。 Since it is an inner class, it is even allowed to access the HashMap
's private members. 由于它是一个内部类,甚至允许访问HashMap
的私有成员。
You can see that for example in the Values
class' implementation of the size
method: 您可以在Values
类的size
方法实现中看到:
public int size() {
return size;
}
The Values
class doesn't have a size
member, so that size
refers to the HashMap
's size. Values
类没有size
成员,因此size
指的是HashMap
的大小。 It's equivalent to: 它相当于:
public int size() {
return HashMap.this.size;
}
EDIT: Note that this also means that the collection you receive is not a copy, but still refers to the original HashMap
contents and therefore changes when you update the HashMap
: 编辑:请注意,这也意味着您收到的集合不是副本,但仍然引用原始的HashMap
内容,因此在更新HashMap
时会更改:
// Getting the entry set (not a copy!)
Set<Entry<String, String>> entries = map.entrySet();
// Add elements to the map afterwards
map.put("abc", "def");
// Check out the entries in the collection
// (magically containing the elements added after getting the collection)
System.out.println(entries); // "[abc=def]"
The Values
class implements a Collection
that is backed by the HashMap
. Values
类实现了由HashMap
支持的Collection
。 As mastov commented, Values
is an inner class of HashMap
, which gives it access to the members of the enclosing HashMap
instance it is associated with. 正如mastov所评论的, Values
是HashMap
的内部类,它允许访问与之关联的封闭HashMap
实例的成员。 Therefore it's not empty. 因此它不是空的。 Its size is the size of the HashMap
, and when you iterate over it, you are iterating over the Entries of the HashMap
. 它的大小是HashMap
的大小,当你迭代它时,你正在迭代HashMap
的条目。
When you call System.out.println(values);
当你调用System.out.println(values);
, you are calling the toString
method of AbstractCollection
, which uses an Iterator
to iterate over the values and get their String
representation. ,您正在调用AbstractCollection
的toString
方法,该方法使用Iterator
迭代值并获取其String
表示形式。 The Iterator
actually iterates over the Entries of the HashMap
and returns their values. Iterator
实际上遍历HashMap
的条目并返回它们的值。
The same goes for the Set
s returned by keySet
and entrySet
. 对于keySet
和entrySet
返回的Set
,情况也是如此。
Collection<V> vs = values;
return (vs != null ? vs : (values = new Values()));
These two line answer your question. 这两行回答了你的问题。
values
is a internal collection (Inherited from AbstractMap
). values
是一个内部集合(从AbstractMap
继承)。 If it is not null
then it will be returned. 如果它不为null
则返回它。
If it is null
then it will be initialized and the new one will returned. 如果它为null
则它将被初始化并返回新的。
Now I guess, the main point of your question is 现在我想,你的问题的主要观点是
when and how do these methods return objects with elements we need? 何时以及如何使用我们需要的元素返回对象?
Technically values
always return this initialized Object. 技术上, values
始终返回此初始化对象。 Then how we get our entry values from these object.? 那么我们如何从这些对象中获取入口值。
Lets go a little deep: 让我们走得更远:
values() actually return an object of class Values
which is an Inner class of HashMap
and extends AbstractCollection
values()实际上返回类Values
的对象,它是HashMap
的Inner类,并扩展了AbstractCollection
private final class Values extends AbstractCollection<V>
As you have looked into the source code. 正如您已查看源代码。 Then you will find inside the Values
class 然后你会在Values
类中找到它
public Iterator<V> iterator() {
return newValueIterator();
}
this newValueIterator()
does the trick. 这个newValueIterator()
可以解决问题。
If you go more deeper you will find newValueIterator()
returns object of ValueIterator
which is a subclass of HashIterator
HashIterator
implements basic functionality for iteration, which actually itterate over the table
maintained by the HashMap
. 如果你更深入,你会发现newValueIterator()
返回ValueIterator
对象,它是HashIterator
的子类HashIterator
实现迭代的基本功能,它实际上是在HashMap
维护的table
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.