零
一、IdentityHashMap是个咋子嘛
Java中HashMap是我们常用的一种map了,Hashmap的特点之一就是key值不重复,那有同学要问了,有些时候我需要重复的key怎么办呢?好说,Java给我们准备了IdentityHashMap这种key可以重复的map。
这种map的特点就是对比key的时候,是相同的引用才算相同。可以这样理解,HashMap比较的时候使用的是equal(这里指String重写的那个equal),对象相同才相同,也就是(在String中)内容相同才相同,而IdentityHashMap使用的是==,引用相同才相同,也就是要指向同一个对象才可以。
二、咋子用这个Map?
使用方法和HashMap大同小异,有put、get方法,有isEmpty、size等等。下面给出个例子。
IdentityHashMap<String, String> identityHashMap = new IdentityHashMap();
String s1 = new String("test");
String s2 = new String("test");
identityHashMap.put(s1,"value");
identityHashMap.put(s2,"value1");
在get的时候就需要注意一点,get返回的只有一条数据,即使有多个相同的key。这点在源码中有很好的体现:
public V get(Object key) {
Object k = maskNull(key);
Object[] tab = table;
int len = tab.length;
int i = hash(k, len);
while (true) {
Object item = tab[i];
if (item == k)
return (V) tab[i + 1];
if (item == null)
return null;
i = nextKeyIndex(i, len);
}
}
想要全部读出来的话推荐的做法是使用map的entryset。
三、就这?你的思考呢?
在使用IdentityHashMap中,可能会遇到一些奇怪的问题。比如这样:
IdentityHashMap<String, String> identityHashMap = new IdentityHashMap();
String s1 = new String("test");
String s2 = new String("test");
identityHashMap.put(s1,"value");
identityHashMap.put(s2,"value1");
System.out.println(identityHashMap.get("test"));
System.out.println(identityHashMap);
得出来的结果是什么呢?
或者这样:
IdentityHashMap<String, String> identityHashMap = new IdentityHashMap();
String s1 = "test";
String s2 = "test";
identityHashMap.put(s1,"value");
identityHashMap.put(s2,"value1");
System.out.println(identityHashMap.get("test"));
System.out.println(identityHashMap);
结果呢?
其实真相只有一个,小心String类。
四、String的那些事
这就不得不说一下String类了,String作为常用的数据类型,但是很难意识到String并不是基本数据类型,而是封装好的一个类,还是final,这就造成了String类有很多有意思的地方。之前看到一个文章讲解了String类,十分全面清晰,可以点这里去学习一个。
这里小德可以简单介绍一下,看着两句话:
String s1 = "test";
String s2 = new String("test2");
对于s1来说创建过程是这样的:首先"test"是个字符串常量,就检查常量池中有没有"test"这个常量,没有的话添加一个,然后s1就直接指向这个常量。
但s2过程就曲折了很多,首先s2是new出来的,所以在堆中给s2分配个空间来保存这个String对象,然后这个对象在指向常量池中的"test2"(同样,没有的话创建一个)。
回到我们那两个问题中,对于第一个问题,s1,s2是new出来的,所以指向堆中的空间,而我们get的时候使用的是"test",字符串常量啊这是,直接指向了常量池,所以get的时候这两者之间是不同的引用,返回的null。
而第二个问题就很明显了,s1和S2都是直接指向了常量池中的"test",所以在put的时候把这两个当做同一个了。
还希望像我这样的初学者打好基础,深入了解Java的一些机制。
O了个八倍镜消音98K
//作为Android开发的初学者,如果我有错误的地方或者不足的话欢迎大家指正。希望与大家一同进步