为什么要同时重写equals方法和hashCode方法(详解)

365bet娱乐场开户 2025-07-02 09:05:57 admin 阅读 5859
为什么要同时重写equals方法和hashCode方法(详解)

在解释为什么要重写equals方法和hashcode方法时,我们要先了解一下这样重写的目的是什么,也让自己有一个思路,围绕这个思路去思考问题,能更好的整握其中的缘由,针对这个目的去思考为什么要去重写,重写的作用是什么,以及如何去重写它们。

一、重写equals方法和hashcode方法的目的

在做对象间的比较时,我们通常采用equals方法来判断它们是否相等,如果地址值不同,则俩个对象不等。那为什么我们还要重写这俩个方法,换句话说,重写这俩个方法的目的在哪。 首先,我们思考这样一个需求:当一个数据表中有A和B俩个人,只要他们的名字和身份证这俩个字段相等,那么我们就认定这俩个人是同一个人,不去考虑他们的地址值是否相等来比较这俩个人是不是同一个人。 再有,这样一个情形:我们用一个拼接好的hello world的字符串和一个new出来的hello world作比较,只要内容一样,则俩个变量相等,如果只用equals来比较的话,他们势必不相等。 所以,重写equals方法和hashcode方法的目的就是为了实现一些合乎情理,切实际,在现实生活中经常出现的一些情景,针对这些情景来提出一些需求,为了满足这个需求从而采取的措施。如果不重写的话,在他的源码中比较的是俩个对象的地址值。

二、为什么要同时重写equals方法和hashcode方法

了解目的之后,所以我们需要重写这俩个方法,那只重写其中的一个方法可行嘛?我们来分析一下: 只重写equals方法:这种方法是可行的,但是假如有这样一个情况,在做俩个对象A和B的比较时,B对象是存放在集合里的,且集合里的数据多达几万条,那我们还要调用equals方法来一个一个比较嘛,当然可以,但是这样的话,效率就必然成了一个问题,所以,这个时候,就需要我们的hashcode方法了。 只重写hashcode方法呢:在做对象之间的比较时,我们要知道:

如果equals方法相等,则他们hsahcode的hash值必然相等,俩个对象必然相等如果equals方法不等,则他们hashcode的hash值不一定不等,俩个对象必然不等如果hashcode的hash值不等,则俩个对象必然不等如果hashcode的hash值相等,俩个对象不一定相等,要在判断equals是否相等来比较俩个对象是否相等。 所以,需要同时重写equals方法和hashcode方法。

三、重写equals方法和hashcode方法的作用

其实,如果看懂了上文的话,这里也就知道了重写这俩个方法的作用, 第一点:就是为了更加高效的去比较俩个对象是否相等。 第二点:实现特殊的需求。

四、如何重写equals方法和hashcode方法

在重写的过程中,我们要遵守equals方法和hashcode方法的特性,也就是要一一证明它的特性。 1.equals方法的特性: (1)自反性:对于任何非空引用x,x.equals(x)应该返回true; (2)对称性:对于任何引用x,和y,当且仅当,y.equals(x)返回true,x.equals(y)也应该返回true; (3)传递性:对于任何引用x,y,z,如果x.equals(y)返回true,y.equals(z)返回true,那么x.equals(z)也应该返回true; (4)一致性:如果x,y引用的对象没有发生变化,反复调用x.equals(y)应该返回同样的结果; (5)对于任意非空引用x,x.equals(null)返回false; 2.而hashcode方法的特性: (1)HashCode的存在主要是用于查找的快捷性,如Hashtable,HashMap等,HashCode经常用于确定对象的存储地址; (2)如果两个对象相同, equals方法一定返回true,并且这两个对象的HashCode一定相同; (3)两个对象的HashCode相同,并不一定表示两个对象就相同,即equals()不一定为true,只能够说明这两个对象在一个散列存储结构中。 (4)如果对象的equals方法被重写,那么对象的HashCode也尽量重写,以保证equals方法相等时两个对象hashcode返回相同的值(eg:Set集合中确保自定义类的成功去重)。 3.如何重写equals方法和hashcode方法 自己摸索,哈哈哈。

public class User {

private String id;

private String name;

private String age;

public User(){

}

public User(String id, String name, String age){

this.id = id;

this.name = name;

this.age = age;

}

public String getId() {

return id;

}

public void setId(String id) {

this.id = id;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public String getAge() {

return age;

}

public void setAge(String age) {

this.age = age;

}

@Override

public String toString() {

return this.id + " " + this.name + " " + this.age;

}

@Override

public boolean equals(Object obj) {

if(this == obj){

return true;//地址相等

}

if(obj == null){

return false;//非空性:对于任意非空引用x,x.equals(null)应该返回false。

}

if(obj instanceof User){

User other = (User) obj;

//需要比较的字段相等,则这两个对象相等

if(equalsStr(this.name, other.name)

&& equalsStr(this.age, other.age)){

return true;

}

}

return false;

}

private boolean equalsStr(String str1, String str2){

if(StringUtils.isEmpty(str1) && StringUtils.isEmpty(str2)){

return true;

}

if(!StringUtils.isEmpty(str1) && str1.equals(str2)){

return true;

}

return false;

}

@Override

public int hashCode() {

int result = 17;

result = 31 * result + (name == null ? 0 : name.hashCode());

result = 31 * result + (age == null ? 0 : age.hashCode());

return result;

}

}

相关文章

德国队0-6惨败,巴西:我们当年是怎么输7个的?
苏宁易购售后怎么样?退换货方便吗?
超实用,教你一招轻松将照片修改为一寸尺寸