一、 Object中的源码
1. Object中的equals方法
1. Object中的 equals()方法:观察可知比较的是 toString()的返回值
public boolean equals(Object obj) {
return (this == obj);
}
2. Object中的 toString()方法:观察可知左边会获取含包名的类名,右边获取hashCode值并把
hasCode转换为十六进制。
所以,equals比较两个类是否相同,主要还是比较他们是否是同一个类,以及他们的
hashCode值是否相同
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
2. Object中的hashCode()方法
https://www.cnblogs.com/dolphin0520/p/3681042.html (参考文章)
https://blog.youkuaiyun.com/xusiwei1236/article/details/45152201 (参考文章)
https://blog.youkuaiyun.com/fenglibing/article/details/8905007 (hashCode的作用)
注意:hashCode()
的注释指出了Object.hashCode()
在JRE(Java Runtime Library)中应该遵循的一些契约(contract)
(PS:即使我们看不到源码,但是它的生成规则一定会遵守下面这个3个契约)
-
一致性(
consistent
),在程序的一次执行过程中,对同一个对象必须一致地返回同一个整数。 -
如果两个对象通过
equals(Object)
比较,结果相等,那么对这两个对象分别调用hashCode
方法应该产生相同的整数结果。(PS:这里equals
和hashCode
说的都是Object类的) -
如果两个对象通过
java.lang.Object.equals(java.lang.Ojbect)
比较,结果不相等,不必保证对这两个对象分别调用hashCode
也返回两个不相同的整数。
Object中的 hashCode()方法:观察可知它是由原生函数而生成的,并且它的值是根据对象中的值生成的
native :使用native关键字修饰的函数(方法),说明这个方法是原生函数,也就是这个方法
是用C/C++语言实现的,并且被编译成了DLL,由java去调用。
public native int hashCode();
3. 总结(Object中)
equals
主要比较的就是两个对象的值是否相等,它的比较规则是“类全名 + @ + hasCode值”
。- 从源码可知,为什么
equals()
比较相等的两个数,hasCode
一定相等;equals()
比较两个数不相等,hasCode
不一定相等 - hashCode返回的并不一定是对象的(虚拟)内存地址,具体取决于运行时库和JVM的具体实现
- System.identityHashCode(obj)这个方法是根据内存地址获取的hash值,每次运行程序时,内存会为对象重新分配内存地址,因此得到的hash值也不一样。
二、 String中的源码
1. String中的hashCode方法
1. String中的 hashCode()方法:首先把String中的变量hash赋值给要返回的变量h,再判断赋
值之后是否为空,为空则计算hash值。并返回计算好的hash值。
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value;
for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}
2. String中的equals()方法
1. String中的 equals()方法:1. 首先比较传入对象和当前对象的内容是否相等(this直接使用
调用的是toString方法,toString会直接返回字符串内容),比较字符串
内容相等则直接返回true。
2.不相等则判断是否为相同类型,再判断字符串长度是否相等, 最后
通过while循环比较两个字符串内容是否相等
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
3. 总结(String中)
- 对
Object
中的两个方法都进行了重写,且重写后的hashCode
与equals
没有了关联。 - 重写后的
equals
主要是比较两个字符串的内容是否相等
,Object
中的是主要是比较是否是同一个类 + hashCode是否相等
三、 重写hashCode与equals
1. equals方法
1. 自己重写的equals方法:1. 先判断传入对象与当前对象toString值是否相同
@Override
public boolean equals(Object that) {
if (this == that) {
return true;
}
if (that == null) {
return false;
}
if (getClass() != that.getClass()) {
return false;
}
OrgActivityAssistLike other = (OrgActivityAssistLike) that;
return (this.getLikeId() == null ? other.getLikeId() == null : this.getLikeId().equals(other.getLikeId()))
&& (this.getActivityId() == null ? other.getActivityId() == null : this.getActivityId().equals(other.getActivityId()))
&& (this.getOrderId() == null ? other.getOrderId() == null : this.getOrderId().equals(other.getOrderId()))
&& (this.getCustomerId() == null ? other.getCustomerId() == null : this.getCustomerId().equals(other.getCustomerId()))
&& (this.getCreateTime() == null ? other.getCreateTime() == null : this.getCreateTime().equals(other.getCreateTime()))
&& (this.getUpdateTime() == null ? other.getUpdateTime() == null : this.getUpdateTime().equals(other.getUpdateTime()));
}
2. 重写的toString方法
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(getClass().getSimpleName());
sb.append(" [");
sb.append("Hash = ").append(hashCode());
sb.append(", assistOrderId=").append(assistOrderId);
sb.append(", helpOrderMoney=").append(helpOrderMoney);
sb.append(", activityId=").append(activityId);
sb.append(", orderId=").append(orderId);
sb.append(", customerId=").append(customerId);
sb.append(", createTime=").append(createTime);
sb.append(", updateTime=").append(updateTime);
sb.append(", serialVersionUID=").append(serialVersionUID);
sb.append("]");
return sb.toString();
}
2. hashCode()方法
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((getLikeId() == null) ? 0 : getLikeId().hashCode());
result = prime * result + ((getActivityId() == null) ? 0 : getActivityId().hashCode());
result = prime * result + ((getOrderId() == null) ? 0 : getOrderId().hashCode());
result = prime * result + ((getCustomerId() == null) ? 0 : getCustomerId().hashCode());
result = prime * result + ((getCreateTime() == null) ? 0 : getCreateTime().hashCode());
result = prime * result + ((getUpdateTime() == null) ? 0 : getUpdateTime().hashCode());
return result;
}