使用Map时遇到的一个坑
问题描述
下述代码执行结果为NULL值
public static void main(String[] args) {
Map<String,String> map = new HashMap<String,String>();
Integer i=1;
map.put("1","value");
System.out.println(map.get(i));
}
问题原因
造成这样的问题原因实质为Key的类型不同而造成的。
从源码看为什么出现此问题
①为什么类型不对但是这样写不报错?
Map是一个接口,定义了get(Object obj)方法,其中get()方法中的参数为Object,所以写什么都不报错。
②abstractMap实现了Map接口,并重写了get()方法。
③HashMap继承了abstractMap,所以HashMap声明的对象map执行的是abstractMap的get方法。
public V get(Object key) {
Iterator<Entry<K,V>> i = entrySet().iterator();
if (key==null) {
while (i.hasNext()) {
Entry<K,V> e = i.next();
if (e.getKey()==null)
return e.getValue();
}
} else {
while (i.hasNext()) {
Entry<K,V> e = i.next();
if (key.equals(e.getKey()))
return e.getValue();
}
}
return null;
}
④abstractMap的get方法逻辑是遍历map集合,只要传过来的key与map里面的一个key相等就返回它对应的value。
⑤而判断两个key相等使用的是equals方法。
⑥而equals的底层是通过判断一个对象是不是另一个对象的实例。如A.equals(B) 实则判断 B instanceof A。
public boolean equals(Object obj) {
if (obj instanceof Long) {
return value == ((Long)obj).longValue();
}
return false;
}
⑦综上,声明的map中key为String类型,而调用get方法中传入了Integer类型的对象。在底层执行equals是自然判断String不是Integer的实例。故返回NULL
如何解决避免
一定要将类型进行转换,如使用String.valueOf()将其他类型的转换为字符串类型。