- 现象
map.get(Object key)为null,我很确定这个key是我传进去并且自认为是与put进去的值相等。 - 过程
我有一个用于储存成绩信息的坐标(key)及成绩值(value)的LinkedHashMap:
private LinkedHashMap<Location, String> gradesMap = new LinkedHashMap<>();
Location类如下(为了篇幅,去掉了getter和setter方法):
public class Location {
public Location(Integer row, Integer column) {
this.row = row;
this.column = column;
}
private Integer row;
private Integer column;
@Override
public boolean equals(Object obj) {
Location location = (Location) obj;
return column.equals(location.getColumn()) && row.equals(location.getRow());
}
}
重写了equals是为了使得当Location两个属性分别相等时对象引用就相同。即形如locationA.equals(locationB)这种。我还做了测试:
Location a = new Location(1,1);
Location b = new Location(1,1);
LOGGER.info("相等不:{}", a.equals(b));
输出结果为true。
这里是为了解析如下图所示的excel里面的数据使用:
按行解析后,将
最后按照预想的做法取出map中的值:
结果发现这个value始终为null。
很不甘心,又做了个实验:
输入结果也为null,这时候开始怀疑人生了,按道理说,key都是同一个了,为啥获取到值还是空的。于是就去翻这个map.get(Object key)方法:
这是LinkedHashMap中的get方法源码,一眼我就瞧见了这个醒目的hash单词,果断去Location类重写了下hashCode方法:
运行成功!
- 原因
我想大概是因为要确定两个对象是否相等需要equals与hashcode同时满足吧。
找了些资料供参考,后续研究完善。
Java面试题之为什么要重写hashcode( )和equals( )?
重写equals和hashCode的区别
重温:Java hashCode() 和 equals()的若干问题解答
引用大佬的理解:
对于不会使用到散列表(HashSet, Hashtable, HashMap)来装载对象的情况,才会使用到hashCode,本文刚好是HashMap,本质就是两个对象按照super.hashCode()生成的结果不同,造成equals比较两个对象不相等,故要重写hashCode使用自己的算法让计算后的值相同。