![](/img/trans.png)
[英]Will hashmap.keyset() return keys in the order they were added to the hashmap?
[英]How can HashMap.keySet() return a view of keys?
這是java.util.HasMap類中的keySet()函數:
public Set<K> keySet() {
Set<K> ks = keySet;
if (ks == null) {
ks = new KeySet();
keySet = ks;
}
return ks;
}
在評論中,它說這個功能
返回此映射中包含的鍵的{@link Set}視圖。 該集由地圖支持,因此對地圖的更改將反映在集中,反之亦然。
因此,我期望KeySet類型的對象,此函數返回的對象將包含對“視圖鍵”的引用。 但是,當我查看代碼時,KeySet類根本不包含任何字段及其所有超類。
final class KeySet extends AbstractSet<K> {
public final int size() { return size; }
public final void clear() { HashMap.this.clear(); }
public final Iterator<K> iterator() { return new KeyIterator(); }
public final boolean contains(Object o) { return containsKey(o); }
public final boolean remove(Object key) {
return removeNode(hash(key), key, null, false, true) != null;
}
public final Spliterator<K> spliterator() {
return new KeySpliterator<>(HashMap.this, 0, -1, 0, 0);
}
public final void forEach(Consumer<? super K> action) {
Node<K,V>[] tab;
if (action == null)
throw new NullPointerException();
if (size > 0 && (tab = table) != null) {
int mc = modCount;
for (int i = 0; i < tab.length; ++i) {
for (Node<K,V> e = tab[i]; e != null; e = e.next)
action.accept(e.key);
}
if (modCount != mc)
throw new ConcurrentModificationException();
}
}
}
有人可以解釋一下
為了更清楚:
這是打印出鍵集值的代碼示例。 雖然KeySet對象保存對包含的地圖數據的引用,但是如何准確地輸出關鍵數據而不是地圖的其他數據(不是值數據或其他任何數據)。 什么是告訴這個KeySet對象只保存MapKeys? 我在代碼中看不到這樣的指令。
package com.tutorialspoint;
import java.util.*;
public class HashMapDemo {
public static void main(String args[]) {
// create hash map
HashMap newmap = new HashMap();
// populate hash map
newmap.put(1, "tutorials");
newmap.put(2, "point");
newmap.put(3, "is best");
// get keyset value from map
Set keyset = newmap.keySet();
// check key set values
System.out.println("Key set values are: " + keyset);
}
}
輸出:
鍵集值為:[1,2,3]
“ 視圖 ”是一種對象,其數據由不同的對象支持,但以不同的方式提供。 在這種情況下,它提供Map
的鍵的“視圖”作為Set
。 這對用戶和性能都有很多好處。
值得注意的是,由於它與支持類共享其數據,因此內存開銷非常小 - 它不需要將所有鍵復制到一個全新的Set
。 此外,用戶無需擔心視圖與支持結構不同步 - 添加和刪除將立即通過視圖顯示。
因為KeySet
是一個內部類,所以它可以訪問其包含類( HashMap
)的實例的字段。 請注意代碼段中的HashMap.this
表示法。
size()
的return size;
是對HashMap
的size
字段的引用 clear()
的HashMap.this.clear();
調用HashMap
的clear()
方法(它需要使用HashMap.this
來引用map的clear()
方法而不是它自己的方法) contains()
代表HashMap
的containsKey()
方法-這並不需要HashMap.this
因為KeySet
沒有碰撞containsKey()
方法 remove()
類似地委托給HashMap
的removeNode()
如果它被聲明為final static class KeySet
那么它將是一個靜態嵌套類,它不依賴於包含類的實例(它只是組織相關類的一種方式)。 在這種情況下, KeySet
需要一個顯式的HashMap
字段,並且需要將有問題的地圖傳遞給構造函數。 內部類使這隱含(這是簡潔的,但有時令人困惑)。
什么是告訴這個KeySet對象只保存MapKeys?
要明確的是,沒有這樣的指示。 KeySet
實例可以傳遞地訪問支持映射的所有字段和方法。 但是您的示例( System.out.println("Key set values are: " + keyset);
keyset.toString()
System.out.println("Key set values are: " + keyset);
)隱式調用keyset.toString()
,這是(有意)未實現以返回映射的值。 因為KeySet
擴展了AbstractSet
(后者又擴展了AbstractCollection
),所以.toString()
依賴於KeySet
的iterator()
實現,該實現提供了映射鍵的迭代器,而不是其值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.