分析HashMap 的 JDK 源碼
緣由:今天好友拿著下面的代碼,問我為什么 Map.Entry 這個接口沒有實現(xiàn) getKey() 和 getValue() 方法,卻可以使用,由此,開啟了一番查閱 JDK 源碼的旅途….
Map map = new HashMap(); map.put(1, "張三"); map.put(2, "李四"); map.put(3, "王五"); map.put(4, "趙六"); map.put(5, "錢七"); Set set = map.entrySet(); for (Object object : set) { Map.Entry entry = (Map.Entry) object; System.out.println(entry.getKey() + "-->" + entry.getValue()); }
1.首先,我們看 map 對象,這個 map 對象是 HashMap 的一個實例,然后下面的 Set set = map.entrySet(); 可以知道這其實用的 HashMap 實現(xiàn)的 entrySet() 方法,然后我們可以查看 HashMap 里 entrySet() 的源碼
從源碼可以看出,這里的返回了一個 EntrySet
對象,但是需要注意的是這個 EntrySet
是 HashMap
里的一個內部類,源碼如下:
final class EntrySet extends AbstractSet<Map.Entry<K,V>> { public final int size() { return size; } public final void clear() { HashMap.this.clear(); } public final Iterator<Map.Entry<K,V>> iterator() { return new EntryIterator(); } public final boolean contains(Object o) { if (!(o instanceof Map.Entry)) return false; Map.Entry<?,?> e = (Map.Entry<?,?>) o; Object key = e.getKey(); Node<K,V> candidate = getNode(hash(key), key); return candidate != null && candidate.equals(e); } public final boolean remove(Object o) { if (o instanceof Map.Entry) { Map.Entry<?,?> e = (Map.Entry<?,?>) o; Object key = e.getKey(); Object value = e.getValue(); return removeNode(hash(key), key, value, true, true) != null; } return false; } public final Spliterator<Map.Entry<K,V>> spliterator() { return new EntrySpliterator<>(HashMap.this, 0, -1, 0, 0); } public final void forEach(Consumer<? super Map.Entry<K,V>> 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); } if (modCount != mc) throw new ConcurrentModificationException(); } } }
從這里我們是可以看出,這個 EntrySet
其實是封裝的一個 Node
類的實體。也就是說我們的 set
其實就是這個 Node
對象。
2.現(xiàn)在我們來說說這個 Node 對象,Node 對象也是 HashMap 里的一個內部類,源碼如下:
static class Node<K,V> implements Map.Entry<K,V> { final int hash; final K key; V value; Node<K,V> next; Node(int hash, K key, V value, Node<K,V> next) { this.hash = hash; this.key = key; this.value = value; this.next = next; } public final K getKey() { return key; } public final V getValue() { return value; } public final String toString() { return key + "=" + value; } public final int hashCode() { return Objects.hashCode(key) ^ Objects.hashCode(value); } public final V setValue(V newValue) { V oldValue = value; value = newValue; return oldValue; } public final boolean equals(Object o) { if (o == this) return true; if (o instanceof Map.Entry) { Map.Entry<?,?> e = (Map.Entry<?,?>)o; if (Objects.equals(key, e.getKey()) && Objects.equals(value, e.getValue())) return true; } return false; } }
可以看出來,這個 Node
對象是 Map.Entry<K,V>
的實現(xiàn)類,我們可以看到這個 Node
對象實現(xiàn)了 getKey()
和 getValue()
的方法,所以后面調用的 entry.getKey()
以及 entry.getValue()
方法其實都是調用的 Node 對象里的getKey()
和 getValue()
方法,這里就是 Java 的多態(tài)的一種表現(xiàn)。
3.至此,打完收槍!
以上就是分析HashMap 的 JDK 源碼的詳細內容,更多關于HashMap 的 JDK 源碼的資料請關注腳本之家其它相關文章!
相關文章
ReentrantReadWriteLock不能鎖升級的原因總結
今天給大家?guī)淼氖顷P于Java并發(fā)的相關知識,文章圍繞著為什么ReentrantReadWriteLock不能鎖升級展開,文中有非常詳細的介紹及代碼示例,需要的朋友可以參考下2021-06-06Java數(shù)據(jù)結構與算法之棧(Stack)實現(xiàn)詳解
這篇文章主要為大家詳細介紹了Java數(shù)據(jù)結構學習筆記第二篇,Java數(shù)據(jù)結構與算法之棧Stack實現(xiàn),具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-09-09Mybatis-plus:${ew.sqlselect}用法說明
這篇文章主要介紹了Mybatis-plus:${ew.sqlselect}用法說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06MyBatis-Plus 如何實現(xiàn)連表查詢的示例代碼
這篇文章主要介紹了MyBatis-Plus 如何實現(xiàn)連表查詢的示例代碼,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-08-08