package test; public class Cat { private String name; private Integer age; public Cat(String name, Integer age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public boolean equals(Object obj) { if (this == obj) { return true; } if (!(obj instanceof Cat)) { return false; } Cat p = (Cat) obj; if (this.name.equals(p.name) && this.age == p.age) { return true; } else { return false; } } public int hashCode() { return this.name.hashCode() * this.age; } public String toString() { return "姓名:" + this.name + ";年龄:" + this.age; } }
测试:
public class TestMap { @SuppressWarnings({ "rawtypes", "unchecked" }) public static void main(String[] args) { Map mp = new HashMap<String, String>(); mp.put("1", "s"); mp.put("2", "t"); /*Collection ct = mp.values(); System.out.println(ct.toString());*/ mp.put("1", "t"); Set<Map.Entry<String, String>> allSet = mp.entrySet(); Iterator<Map.Entry<String, String>> iter = allSet.iterator(); while (iter.hasNext()) { Map.Entry<String, String> me = iter.next(); System.out.println(me.getKey() + " --> " + me.getValue()); } //HashMap Map mpx = new HashMap<Cat, String>(); mpx.put(new Cat("kitty",1), "kitty_1"); mpx.put(new Cat("jime",2), "jime_2"); mpx.put(new Cat("kitty",1), "kitty_2"); Set<Map.Entry<Cat, String>> allSetx = mpx.entrySet(); Iterator<Map.Entry<Cat, String>> iterx = allSetx.iterator(); while (iterx.hasNext()) { Map.Entry<Cat, String> me = iterx.next(); System.out.println(me.getKey() + " --> " + me.getValue()); } System.out.println("==============IdentityHashMap:"); //IdentityHashMap Map imp = new IdentityHashMap<Cat, String>(); imp.put(new Cat("kitty",1), "kitty_1"); imp.put(new Cat("jime",2), "jime_2"); imp.put(new Cat("kitty",1), "kitty_2"); Set<Map.Entry<Cat, String>> iSet = imp.entrySet(); Iterator<Map.Entry<Cat, String>> iterxx = iSet.iterator(); while (iterxx.hasNext()) { Map.Entry<Cat, String> me = iterxx.next(); System.out.println(me.getKey() + " --> " + me.getValue()); } } }
控制台输出:
2 --> t
1 --> t
姓名:jime;年龄:2 --> jime_2
姓名:kitty;年龄:1 --> kitty_2
==============IdentityHashMap:
姓名:kitty;年龄:1 --> kitty_2
姓名:kitty;年龄:1 --> kitty_1
姓名:jime;年龄:2 --> jime_2
查看HashMap的Put(K,V)
public V put(K key, V value) { if (key == null) return putForNullKey(value); int hash = hash(key.hashCode()); int i = indexFor(hash, table.length); for (Entry<K,V> e = table[i]; e != null; e = e.next) { Object k; //比较的是哈希值,key if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; addEntry(hash, key, value, i); return null; }
查看:IdentityHashMap.put(Object obj, Object obj1)
public Object put(Object obj, Object obj1) { Object obj2 = maskNull(obj); Object aobj[] = table; int i = aobj.length; int j; Object obj3; for(j = hash(obj2, i); (obj3 = aobj[j]) != null; j = nextKeyIndex(j, i)) //比较的两个对象 if(obj3 == obj2) { Object obj4 = aobj[j + 1]; aobj[j + 1] = obj1; return obj4; } modCount++; aobj[j] = obj2; aobj[j + 1] = obj1; if(++size >= threshold) resize(i); return null; }
总结:
1.简单说IdentityHashMap与常用的HashMap的区别是:
前者比较key时是“引用相等”而后者是“对象相等”,即对于k1和k2,当k1==k2时,
IdentityHashMap认为两个key相等,而HashMap只有在k1.equals(k2) == true 时才会认为两个key相等。
2.IdentityHashMap 允许使用null作为key和value. 不保证任何Key-value对的之间的顺序,
更不能保证他们的顺序随时间的推移不会发生变化。
3.IdentityHashMap有其特殊用途,比如序列化或者深度复制。或者记录对象代理。
举个例子,jvm中的所有对象都是独一无二的,哪怕两个对象是同一个class的对象
,而且两个对象的数据完全相同,对于jvm来说,他们也是完全不同的,
如果要用一个map来记录这样jvm中的对象,你就需要用IdentityHashMap,而不能使用其他Map实现