HashMap.values()
的源代码如下所示
public Collection<V> values() {
Collection<V> vs = values;
return (vs != null ? vs : (values = new Values()));
}
如您所见,当values()
方法首次调用时,它只返回一个Values
对象。 Values
对象是AbstractCollection
的子类,没有构造函数,当然不包含任何元素。但是当我调用该方法时,它快速返回了一个集合
Collection<String> values = map.values();
System.out.println(values);
那太奇怪了。不仅values()
,而且keySet()
和entrySet()
方法返回此类空对象。所以,这是我的问题,这些方法何时以及如何返回具有我们需要的元素的对象?
答案 0 :(得分:20)
这是一种误解,Values
课程是&#34;当然是空的&#34;。只是因为没有调用它的方法,它的构造函数没有任何参数并不意味着该集合是空的。
Values
班级是一个内部班级&#34; ({1}}的非静态nested class),这意味着它具有对创建它的HashMap
对象的隐式引用。因此,它可以通过使用HashMap
引用或直接访问成员来显式访问HashMap
的所有元素。由于它是一个内部类,甚至可以访问HashMap.this
的私人成员。
例如,您可以在HashMap
课程中看到&#39; Values
方法的实现:
size
public int size() {
return size;
}
班级没有Values
成员,因此size
指的是size
的尺寸。它相当于:
HashMap
编辑:请注意,这也意味着您收到的收藏品不是副本,但仍会引用原始public int size() {
return HashMap.this.size;
}
内容,因此更新{{1}时会发生变化}:
HashMap
答案 1 :(得分:13)
Values
类实现Collection
支持的HashMap
。正如mastov评论的那样,Values
是HashMap
的内部类,它允许访问与之关联的封闭HashMap
实例的成员。因此它不是空的。它的大小是HashMap
的大小,当你迭代它时,你正在迭代HashMap
的条目。
当您致电System.out.println(values);
时,您正在调用toString
AbstractCollection
方法,该方法使用Iterator
来迭代这些值并获取String
表示。 Iterator
实际上迭代HashMap
的条目并返回它们的值。
Set
和keySet
返回的entrySet
也是如此。
答案 2 :(得分:2)
Collection<V> vs = values;
return (vs != null ? vs : (values = new Values()));
这两行回答了你的问题。
values
是一个内部集合(继承自AbstractMap
)。如果不是null
,则会返回
如果是null
,那么它将被初始化并返回新的。
现在我猜,你问题的主要内容是
这些方法何时以及如何使用我们需要的元素返回对象?
技术上values
始终返回此初始化对象。那么我们如何从这些对象中获取入口值。?
让我们走得更远:
values()实际返回类Values
的对象,该对象是HashMap
的内部类并扩展AbstractCollection
private final class Values extends AbstractCollection<V>
您已查看过源代码。然后你会在Values
类
public Iterator<V> iterator() {
return newValueIterator();
}
这个newValueIterator()
可以解决问题
如果你更深入,你会发现newValueIterator()
返回ValueIterator
的对象,HashIterator
是HashIterator
的子类
table
实现了迭代的基本功能,实际上迭代了HashMap
维护的select SUBSTRING('SH1684|32I5', 1, CHARINDEX('|', 'SH1684|32I5') -1) AS ID
。