簡體   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