hashMap 怎么說呢。 我的理解是 外表是一個set 數組,無序不重復 。 每個set元素是一個bean ,存著一對key value
?
看看代碼吧
package test;import java.util.HashMap; import java.util.Map.Entry;public class HashMaptest {public static void main(String[] args) {HashMap<String, String> map = new HashMap<String, String>();String aa = "張三";String bb = "李四";map.put(aa, "22");map.put(bb, "34234");map.put("張三", "223");System.out.println(aa.hashCode());System.out.println(bb.hashCode());for (Entry<String, String> entry : map.entrySet()) {System.out.println(entry.getKey());// System.out.println(entry.getValue()); }}}
打印的結果是:
774889 842061 李四 張三
可以看到, 雖然張三是先插進去的, 但是確在后面打印出來,說明這個數組不是有序的, 不是list;
雖然aa? 的 hashcode=774889 大于bb 的, 肯定不是根據大小插入的,應該是把 得到的hashcode 取余 , 例如? 6%7 = 6 , 9%(7+1)=1 ,6>1? ,所以9 在前面,這里為什么是? 第一個除以7 ,第二個進來確實% 8呢;
因為hash算法是 這樣的:
int hash = key.hashCode(); // 這個hashCode方法這里不詳述,只要理解每個key的hash是一個固定的int值
int index = hash % Entry[].length;
Entry[index] = value;
這里看到? Entry[].length 一直在增加的;
?
所以就會遇到hash沖突, 總有碰到取余后一樣的;
好了,舉個例子:
比如 key="張三", hashcode=666 ,entry的size是 100 ? 666%100=66? ;存在? 66 位置上。? 這個時候 key="李四" 要插入了, hashcode =6666 entry的size是 6600? 6666%6600=66 , 這樣 66 位置就hash沖突了;
這里和我代碼寫的覆蓋不是一回事 。 代碼的 key? 相同,這里在特別說明下:可能有人說, 兩個張三的hashcode 一樣, 不同時候插入,entry 的 size不是不一樣嗎, 那就不會覆蓋了? 這么想是錯誤的, 其實 map 插入的時候是先比較equals? 的, 發現,咦 ,相同, 直接覆蓋原值
:附上 hashMap的Put 方法源碼:
?
final V putVal(int hash, K key, V value, boolean onlyIfAbsent,boolean evict) {Node<K,V>[] tab; Node<K,V> p; int n, i;if ((tab = table) == null || (n = tab.length) == 0)n = (tab = resize()).length;if ((p = tab[i = (n - 1) & hash]) == null)tab[i] = newNode(hash, key, value, null);else {Node<K,V> e; K k;if (p.hash == hash &&((k = p.key) == key || (key != null && key.equals(k))))e = p;else if (p instanceof TreeNode)e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);else {for (int binCount = 0; ; ++binCount) {if ((e = p.next) == null) {p.next = newNode(hash, key, value, null);if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st treeifyBin(tab, hash);break;}if (e.hash == hash &&((k = e.key) == key || (key != null && key.equals(k))))break;p = e;}}if (e != null) { // existing mapping for keyV oldValue = e.value;if (!onlyIfAbsent || oldValue == null)e.value = value;afterNodeAccess(e);return oldValue;}}++modCount;if (++size > threshold)resize();afterNodeInsertion(evict);return null;}
?
?
?
可能比較難懂, 主要在這句:
??? if (e != null) { // existing mapping for key
??????????????? V oldValue = e.value;
??????????????? if (!onlyIfAbsent || oldValue == null)
??????????????????? e.value = value;
??????????????? afterNodeAccess(e);
??????????????? return oldValue;
??????????? }
已存在的key ,之而立是直接覆蓋的。
?