一、背景 ide
今天翻開IdentityHashMap的時候,就傻眼了,這個究竟是個邏輯啊,個人程序代碼以下:性能
1 IdentityHashMap<String,String> identityHashMap=new IdentityHashMap<String, String>(); 2 3 private void initMap(){ 4 identityHashMap.put("zhangsan","age:18"); 5 identityHashMap.put("lisi","age:24"); 6 } 7 8 public String getAge(String name){ 9 return identityHashMap.get(name); 10 } 11 12 public static void main(String[] args) { 13 IdentityHashMapTest test=new IdentityHashMapTest(); 14 test.initMap(); 15 16 String zhangsan=new String("zhangsan"); 17 String lisi=new String("lisi"); 18 System.out.println("zhangsan age is ="+ test.getAge(zhangsan)); 19 System.out.println("lisi age is ="+ test.getAge(lisi)); 20 21 }
運行的結果以下:spa
zhangsan age is =null
lisi age is =null設計
爲何如此呢?code
二、源碼探索orm
This class implements the <tt>Map</tt> interface with a hash table, using
* reference-equality in place of object-equality when comparing keys (and
* values). In other words, in an <tt>IdentityHashMap</tt>, two keys
* <tt>k1</tt> and <tt>k2</tt> are considered equal if and only if
* <tt>(k1==k2)</tt>. (In normal <tt>Map</tt> implementations (like
* <tt>HashMap</tt>) two keys <tt>k1</tt> and <tt>k2</tt> are considered equal
* if and only if <tt>(k1==null ? k2==null : k1.equals(k2))</tt>.)
也就是說IdentityHashMap的用法是,若是兩個key是引用相等的時候,纔會返回存在map裏面的數據,不然返回爲null,並非像HashMap中的只是比較key的值是否相等
(k = p.key) == key || (key != null && key.equals(k))
put方法:blog
1 public V put(K key, V value) { 2 Object k = maskNull(key); 3 Object[] tab = table; 4 int len = tab.length; 5 int i = hash(k, len); 6 7 Object item; 8 while ( (item = tab[i]) != null) { 9 if (item == k) { 10 V oldValue = (V) tab[i + 1]; 11 tab[i + 1] = value; 12 return oldValue; 13 } 14 i = nextKeyIndex(i, len); 15 } 16 17 modCount++; 18 tab[i] = k; 19 tab[i + 1] = value; 20 if (++size >= threshold) 21 resize(len); // len == 2 * current capacity. 22 return null; 23 }
從這裏能夠看出,int i = hash(k, len);必定是一個偶數值,而且這裏使用的while循環操做,可能會有性能問題。ci
這裏key是放在偶數的位置,而value是存放在key對應的下個一個位置中 get
當size>threshold的時候,就會去擴容。源碼
get方法
1 public V get(Object key) { 2 Object k = maskNull(key); 3 Object[] tab = table; 4 int len = tab.length; 5 int i = hash(k, len); 6 while (true) { 7 Object item = tab[i]; 8 if (item == k) 9 return (V) tab[i + 1]; 10 if (item == null) 11 return null; 12 i = nextKeyIndex(i, len); 13 } 14 }
這裏查找value的時候也是使用while循環查找,不斷的去輪詢找key,知道遇到空。
也是使用強引用的比較,若是是key1==key2,纔會返回對應的值。
三、使用場景
如今想一想這中map的設計,也挺有意思的。
好比我想在戶口登記處中找到一個叫張三的,他如今幾歲了?全國叫張三的人這麼多,戶口註冊的時候,又沒有說不能重名,我怎麼知道這個張三是不是你要找的那個張三呢?因此這個時候就可使用IdentityHashMap來存儲了,只有是保證強引用的時候,才能夠找到,不然,我仍是會告訴你,我不知道張三是誰