问题引入
初学java的时候,Map集合给人留下的印象就是键值对{key=value}的存储方式。并且我们知道键值对的key唯一。但是Map容器真的不能存储key值相同的数据吗?查询API才发现有这么一个实现类可以存储重复的key:IdentityHashMap。
IdentityHashMap简介
IdentityHashMap类同样实现了Map接口,拥有Map集合的一切特性。key值同样需要判断是不是重复,根本就是判断的方法和其他Map的实现类不一样。
我们来看看官方的定义: java.util.IdentityHashMap类利用哈希表实现 Map 接口,比较键(和值)时使用引用相等性代替对象相等性。 换句话说,在 IdentityHashMap 中,当且仅当 (k1==k2) 时,才认为两个键 k1 和 k2 相等(在正常 Map 实现(如 HashMap)中,当且仅当满足下列条件时才认为两个键 k1 和 k2 相等:(k1==null ? k2==null : e1.equals(e2)))。
也就是说,IdentityHashMap比较的单单key的值,它不管可以的内存地址还是基本数据类型。而正常的Map实现比较的是具体的内容。
简单的小Demo
public class IdentityHashMapDemo { public static void main(String[] args) { //测试key可以重复的map集合 HashMap<Object, String> map = new HashMap<>(); IdentityHashMap<Object, String> idenMap = new IdentityHashMap<>(); idenMap.put("测试", "成功"); idenMap.put("测试", "失败"); map.put("测试", "成功"); map.put("测试", "失败"); System.out.PRintln("IdentityHashMap运行结果:"+idenMap); System.out.println("HashMap运行结果:"+map); System.out.println("-------------------------------------------------------"); idenMap.put(new String("对象"), "成功"); idenMap.put(new String("对象"), "失败"); map.put(new String("对象"), "成功"); map.put(new String("对象"), "失败"); System.out.println("IdentityHashMap运行结果:"+idenMap); System.out.println("HashMap运行结果:"+map); }}//运行结果/* IdentityHashMap运行结果:{测试=失败} HashMap运行结果:{测试=失败} ------------------------------------------------------ IdentityHashMap运行结果:{对象=成功, 测试=失败, 对象=失败} HashMap运行结果:{测试=失败, 对象=失败}*/结果分析可以看出: 如果存放的是非对象,IdentityHashMap和其他Map的实现没有区别。区别在与可一直存放的对象。使用两次new String() 创建的对象的内存地址必然不会相同,但是指向的内容是相同的。所以HashMap会认为是同一个key从而覆盖前一个key对应的值。但是IdentityHashMap只会去比较key实际的值,也就是内存地址而不会管他具体的内容。所以认为不是同一个key。
Q&AString str = new String("abc")//这句代码到底创建了几个对象?String str = "abc" //该代码和上述代码有什么区别?/* 第一段代码实际创建了两个对象。第二段代码创建了一个对象。("abc")就相当于第二段代码。 这时已经创建了一次对象。再遇到new关键字时,创建第二个对象这个对象保存的是"abc"的内存地址, 并没有真正的指向字符串"abc"。 String str = "abc"是字符串比较特别的创建对象的方式。创建之后会作为常量保存在方法区的常量池中。 它创建对象的时候,会先在常量池中查询有没有已经的存在的字符串常量,如果有就会把其对应的地址给它,如果没有才会创建。*/新闻热点
疑难解答