1、背景
今天翻开IdentityHashMap的时候,就傻眼了,这个到底是个逻辑啊,我的程序代码如下:
1 IdentityHashMap identityHashMap=new IdentityHashMap();2
3 private voidinitMap(){4 identityHashMap.put("zhangsan","age:18");5 identityHashMap.put("lisi","age:24");6 }7
8 publicString getAge(String name){9 returnidentityHashMap.get(name);10 }11
12 public static voidmain(String[] args) {13 IdentityHashMapTest test=newIdentityHashMapTest();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 }
运行的结果如下:
zhangsan age is =null
lisi age is =null
为什么如此呢?
2、源码探索
This class implements the Map interface with a hash table, using
* reference-equality in place of object-equality when comparing keys (and
* values). In other words, in an IdentityHashMap, two keys
* k1 and k2 are considered equal if and only if
* (k1==k2). (In normal Map implementations (like
* HashMap) two keys k1 and k2 are considered equal
* if and only if (k1==null ? k2==null : k1.equals(k2)).)
也就是说IdentityHashMap的用法是,如果两个key是引用相等的时候,才会返回存在map里面的数据,否则返回为null,并不是像HashMap中的只是比较key的值是否相等
(k = p.key) == key || (key != null && key.equals(k))
put方法:
1 publicV 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 returnoldValue;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循环操作,可能会有性能问题。
这里key是放在偶数的位置,而value是存放在key对应的下个一个位置中
当size>threshold的时候,就会去扩容。
get方法
1 publicV 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,才会返回对应的值。
3、使用场景
现在想想这中map的设计,也挺有意思的。
比如我想在户口登记处中找到一个叫张三的,他现在几岁了?全国叫张三的人这么多,户口注册的时候,又没有说不能重名,我怎么知道这个张三是否是你要找的那个张三呢?所以这个时候就可以使用IdentityHashMap来存储了,只有是保证强引用的时候,才可以找到,否则,我还是会告诉你,我不知道张三是谁