Object类里面有默认的equals和hashcode方法,equals是比较两个对象的内存引用是不是一个地址,是则默认为同一个对象,hashcode则是用用了jdk内置的本地方法(c语言实现)计算得出。
这次在项目中,需要用到比较两个对象,我是想两个对象里面的字段值一致则表示它们相等。因此需要重写这两个方法。
千万注意!!如果重写了equals方法,那么hashcode方法也一定要相等。
因为要满足一个约定,就是两个对象相等,那么它们的hashcode也必定相等!!!
static class InoviceInfo {
public InoviceInfo(String relevanceNum, String relevanceCode) {
this.relevanceNum = relevanceNum;
this.relevanceCode = relevanceCode;
}
/**
* 关联蓝字发票号码
*/
private String relevanceNum;
/**
* 关联蓝字发票代码
*/
private String relevanceCode;
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
InoviceInfo that = (InoviceInfo) o;
if (this.relevanceCode == that.relevanceCode && this.relevanceNum == that.relevanceNum) {
return Boolean.TRUE;
} else {
return Boolean.FALSE;
}
}
}
public static void main(String[] args) {
Map<InoviceInfo, String> infoMap = new HashMap<>();
infoMap.put(new InoviceInfo("a", "b"), "1");
System.out.println(infoMap.get(new InoviceInfo("b", "a")));
System.out.println(infoMap.get(new InoviceInfo("a", "b")));
}
如果不重写hashcode 那么会发现,放到map中的值,再用key去取,取不到!!
static class InoviceInfo {
public InoviceInfo(String relevanceNum, String relevanceCode) {
this.relevanceNum = relevanceNum;
this.relevanceCode = relevanceCode;
}
/**
* 关联蓝字发票号码
*/
private String relevanceNum;
/**
* 关联蓝字发票代码
*/
private String relevanceCode;
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
InoviceInfo that = (InoviceInfo) o;
if (this.relevanceCode == that.relevanceCode && this.relevanceNum == that.relevanceNum) {
return Boolean.TRUE;
} else {
return Boolean.FALSE;
}
}
@Override
public int hashCode() {
Map<String, Object> sortedParamMap = new TreeMap<>();
sortedParamMap.put("relevanceNum", this.relevanceNum);
sortedParamMap.put("relevanceCode", this.relevanceCode);
return sortedParamMap.toString().hashCode();
}
}
public static void main(String[] args) {
Map<InoviceInfo, String> infoMap = new HashMap<>();
infoMap.put(new InoviceInfo("a", "b"), "1");
System.out.println(infoMap.get(new InoviceInfo("b", "a")));
System.out.println(infoMap.get(new InoviceInfo("a", "b")));
}
重写之后,会发现,infoMap.put(new InoviceInfo("a", "b"), "1");
放进去的1在后面被取出来了!
hashcode 需要保证,不相等的对象hashcode不同,相同的对象则相同!!
=================
以上代码经过验证是有bug的
这个demo中的例子,之所以会相等,因为
infoMap.put(new InoviceInfo(“a”, “b”), “1”);
System.out.println(infoMap.get(new InoviceInfo(“b”, “a”)));
这两个地方的a和b 被存入了字符串常量池,所以用== 比较时候才会是true
if (this.relevanceCode == that.relevanceCode && this.relevanceNum == that.relevanceNum) {
return Boolean.TRUE;}
换个例子就失效了
比如说:
System.out.println(infoMap.get(new InoviceInfo(new String(“a”), new String(“b”))));
在实际使用中,不可能每次都运气那么好,可以遇到在常量池中的?️!
合理的equals写法如下
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
InoviceInfoDTO that = (InoviceInfoDTO) o;
if (this.relevanceCode==null&&that.relevanceCode!=null){
return Boolean.FALSE;
}
if (this.relevanceNum==null&&that.relevanceNum!=null){
return Boolean.FALSE;
}
if (this.relevanceCode.equals(that.relevanceCode)&& this.relevanceNum.equals( that.relevanceNum)) {
return Boolean.TRUE;
} else {
return Boolean.FALSE;
}
}