繁体   English   中英

HashMap.values()和HashMap.keySet()如何返回值和键?

[英]How do HashMap.values() and HashMap.keySet() return values and keys?

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()方法返回这样的空对象。 那么,这是我的问题,这些方法何时以及如何返回具有我们需要的元素的对象?

错误的观点是, Values类“当然是空的”。 只是因为没有调用它的方法并且它的构造函数没有任何参数并不意味着该集合是空的。

Values类是HashMap的“内部类”(非静态嵌套类 ),这意味着它具有对创建它的HashMap对象的隐式引用。 因此,它可以通过使用HashMap.this引用或直接访问成员来显式访问HashMap所有元素。 由于它是一个内部类,甚至允许访问HashMap的私有成员。

您可以在Values类的size方法实现中看到:

public int size() {
    return size;
}

Values类没有size成员,因此size指的是HashMap的大小。 它相当于:

public int size() {
    return HashMap.this.size;
}

编辑:请注意,这也意味着您收到的集合不是副本,但仍然引用原始的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]"

Values类实现了由HashMap支持的Collection 正如mastov所评论的, ValuesHashMap的内部类,它允许访问与之关联的封闭HashMap实例的成员。 因此它不是空的。 它的大小是HashMap的大小,当你迭代它时,你正在迭代HashMap的条目。

当你调用System.out.println(values); ,您正在调用AbstractCollectiontoString方法,该方法使用Iterator迭代值并获取其String表示形式。 Iterator实际上遍历HashMap的条目并返回它们的值。

对于keySetentrySet返回的Set ,情况也是如此。

Collection<V> vs = values;
return (vs != null ? vs : (values = new Values()));

这两行回答了你的问题。

values是一个内部集合(从AbstractMap继承)。 如果它不为null则返回它。
如果它为null则它将被初始化并返回新的。

现在我想,你的问题的主要观点是
何时以及如何使用我们需要的元素返回对象?

技术上, values始终返回此初始化对象。 那么我们如何从这些对象中获取入口值。
让我们走得更远:

values()实际上返回类Values的对象,它是HashMap的Inner类,并扩展了AbstractCollection

private final class Values extends AbstractCollection<V> 

正如您已查看源代码。 然后你会在Values类中找到它

public Iterator<V> iterator() {
        return newValueIterator();
    }

这个newValueIterator()可以解决问题。
如果你更深入,你会发现newValueIterator()返回ValueIterator对象,它是HashIterator的子类HashIterator实现迭代的基本功能,它实际上是在HashMap维护的table

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM