hashCode与equals的区别与联系经典.docx
- 文档编号:25077826
- 上传时间:2023-06-04
- 格式:DOCX
- 页数:5
- 大小:16KB
hashCode与equals的区别与联系经典.docx
《hashCode与equals的区别与联系经典.docx》由会员分享,可在线阅读,更多相关《hashCode与equals的区别与联系经典.docx(5页珍藏版)》请在冰豆网上搜索。
hashCode与equals的区别与联系经典
hashCode与equals的区别与联系(经典)
一、equals方法的作用1、默认情况(没有覆盖equals方法)下equals方法都是调用Object类的equals方法,而Object的equals方法主要用于判断对象的内存地址引用是不是同一个地址(是不是同一个对象)。
2、要是类中覆盖了equals方法,那么就要根据具体的代码来确定equals方法的作用了,覆盖后一般都是通过对象的内容是否相等来判断对象是否相等。
没有覆盖equals方法代码如下:
[java]viewplaincopy//学生类publicclassStudent{privateintage;privateStringname;publicStudent(){}publicStudent(intage,Stringname){super();this.age=age;this.name=name;}publicintgetAge(){returnage;}publicStringgetName(){returnname;}publicvoidsetAge(intage){this.age=age;}publicvoidsetName(Stringname){this.name=name;}}测试代码如下:
[java]viewplaincopyimportjava.util.HashSet;importjava.util.LinkedList;importjava.util.Set;publicclassEqualsTest{publicstaticvoidmain(String[]args){LinkedList<Student>list=newLinkedList<Student>();Set<Student>set=newHashSet<Student>();Studentstu1=newStudent(3,"张三");Studentstu2=newStudent(3,"张三");System.out.println("stu1==stu2:
"+(stu1==stu2));System.out.println("stu1.equals(stu2):
"+stu1.equals(stu2));list.add(stu1);list.add(stu2);System.out.println("listsize:
"+list.size());set.add(stu1);set.add(stu2);System.out.println("setsize:
"+set.size());}}运行结果:
stu1==stu2:
falsestu1.equals(stu2):
falselistsize:
2setsize:
2结果分析:
Student类没有覆盖equals方法,stu1调用equals方法实际上调用的是Object的equals方法。
所以采用对象内存地址是否相等来判断对象是否相等。
因为是两个新对象所以对象的内存地址不相等,所以stu1.equals(stu2)是false。
3、我们覆盖一下equals方法(age和name属性),让Student类其通过判断对象的内容是否相等来确定对象是否相等。
覆盖后的Student类:
[java]viewplaincopy//学生类publicclassStudent{privateintage;privateStringname;publicStudent(){}publicStudent(intage,Stringname){super();this.age=age;this.name=name;}publicintgetAge(){returnage;}publicStringgetName(){returnname;}publicvoidsetAge(intage){this.age=age;}publicvoidsetName(Stringname){this.name=name;}@Overridepublicbooleanequals(Objectobj){if(this==obj)returntrue;if(obj==null)returnfalse;if(getClass()!
=obj.getClass())returnfalse;Studentother=(Student)obj;if(age!
=other.age)returnfalse;if(name==null){if(other.name!
=null)returnfalse;}elseif(!
name.equals(other.name))returnfalse;returntrue;}}运行结果:
stu1==stu2:
false
stu1.equals(stu2):
true
listsize:
2
setsize:
2
结果分析:
因为Student两个对象的age和name属性相等,而且又是通过覆盖equals方法来判断的,所示stu1.equals(stu2)为true。
注意以上几次测试list和set的size都是2二、HashCode4、通过以上的代码运行,我们知道equals方法已经生效。
接下来我们在覆盖一下hashCode方法(通过age和name属性来生成hashcode)并不覆盖equals方法,其中Hash码是通过age和name生成的。
覆盖hashcode后的Student类:
[java]viewplaincopy//学生类publicclassStudent{privateintage;privateStringname;publicStudent(){}publicStudent(intage,Stringname){super();this.age=age;this.name=name;}publicintgetAge(){returnage;}publicStringgetName(){returnname;}publicvoidsetAge(intage){this.age=age;}publicvoidsetName(Stringname){this.name=name;}@OverridepublicinthashCode(){finalintprime=31;intresult=1;result=prime*result+age;result=prime*result+((name==null)?
0:
name.hashCode());returnresult;}}运行结果:
stu1==stu2:
false
stu1.equals(stu2):
false
listsize:
2
hashCode:
775943
hashCode:
775943
setsize:
2结果分析:
我们并没有覆盖equals方法只覆盖了hashCode方法,两个对象虽然hashCode一样,但在将stu1和stu2放入set集合时由于equals方法比较的两个对象是false,所以就没有在比较两个对象的hashcode值。
5、我们覆盖一下equals方法和hashCode方法。
Student代码如下:
[java]viewplaincopy//学生类publicclassStudent{privateintage;privateStringname;publicStudent(){}publicStudent(intage,Stringname){super();this.age=age;this.name=name;}publicintgetAge(){returnage;}publicStringgetName(){returnname;}publicvoidsetAge(intage){this.age=age;}publicvoidsetName(Stringname){this.name=name;}@OverridepublicinthashCode(){finalintprime=31;intresult=1;result=prime*result+age;result=prime*result+((name==null)?
0:
name.hashCode());System.out.println("hashCode:
"+result);returnresult;}@Overridepublicbooleanequals(Objectobj){if(this==obj)returntrue;if(obj==null)returnfalse;if(getClass()!
=obj.getClass())returnfalse;Studentother=(Student)obj;if(age!
=other.age)returnfalse;if(name==null){if(other.name!
=null)returnfalse;}elseif(!
name.equals(other.name))returnfalse;returntrue;}}
运行结果:
stu1==stu2:
falsestu1.equals(stu2):
truelistsize:
2hashCode:
775943hashCode:
775943setsize:
1结果分析:
stu1和stu2通过equals方法比较相等,而且返回的hashCode值一样,所以放入set集合中时只放入了一个对象。
6、下面我们让两个对象equals方法比较相等,但hashCode值不相等试试。
Student类的代码如下:
[java]viewplaincopy//学生类publicclassStudent{privateintage;privateStringname;<spanstyle="color:
#ff0000;">privatestaticintindex=5;</span>publicStudent(){}publicStudent(intage,Stringname){super();this.age=age;this.name=name;}publicintgetAge(){returnage;}publicStringgetName(){returnname;}publicvoidsetAge(intage){this.age=age;}publicvoidsetName(Stringname){this.name=name;}@OverridepublicinthashCode(){finalintprime=31;intresult=1;result=prime*result+<spanstyle="color:
#ff0000;">(age+index++)</span>;result=prime*result+((name==null)?
0:
name.hashCode());<spanstyle="color:
#ff0000;">System.out.println("result:
"+result);</span>returnresult;}@Overridepublicbooleanequals(Objectobj){if(this==obj)returntrue;if(obj==null)returnfalse;if(getClass()!
=obj.getClass())returnfalse;Studentother=(Student)obj;if(age!
=other.age)returnfalse;if(name==null){if(other.name!
=null)returnfalse;}elseif(!
name.equals(other.name))returnfalse;returntrue;}}运行结果:
stu1==stu2:
false
stu1.equals(stu2):
true
listsize:
2
hashCode:
776098
hashCode:
776129
setsize:
2结果分析:
虽然stu1和stu2通过equals方法比较相等,但两个对象的hashcode的值并不相等,所以在将stu1和stu2放入set集合中时认为是两个不同的对象。
7、修改stu1的某个属性值Student代码如下:
[java]viewplaincopy//学生类publicclassStudent{privateintage;privateStringname;publicStudent(){}publicStudent(intage,Stringname){super();this.age=age;this.name=name;}publicintgetAge(){returnage;}publicStringgetName(){returnname;}publicvoidsetAge(intage){this.age=age;}publicvoidsetName(Stringname){this.name=name;}@OverridepublicinthashCode(){finalintprime=31;intresult=1;result=prime*result+age;result=prime*result+((name==null)?
0:
name.hashCode());System.out.println("hashCode:
"+result);returnresult;}@Overridepublicbooleanequals(Objectobj){if(this==obj)returntrue;if(obj==null)returnfalse;if(getClass()!
=obj.getClass())returnfalse;Studentother=(Student)obj;if(age!
=other.age)returnfalse;if(name==null){if(other.name!
=null)returnfalse;}elseif(!
name.equals(other.name))returnfalse;returntrue;}}测试代码如下:
[java]viewplaincopyimportjava.util.HashSet;importjava.util.LinkedList;importjava.util.Set;publicclassEqualsTest{publicstaticvoidmain(String[]args){LinkedList<Student>list=newLinkedList<Student>();Set<Student>set=newHashSet<Student>();Studentstu1=newStudent(3,"张三");Studentstu2=newStudent(3,"张三");System.out.println("stu1==stu2:
"+(stu1==stu2));System.out.println("stu1.equals(stu2):
"+stu1.equals(stu2));list.add(stu1);list.add(stu2);System.out.println("listsize:
"+list.size());set.add(stu1);set.add(stu2);System.out.println("setsize:
"+set.size());stu1.setAge(34);System.out.println("removestu1:
"+set.remove(stu1));System.out.println("setsize:
"+set.size());}}运行结果:
stu1==stu2:
false
stu1.equals(stu2):
true
listsize:
2
hashCode:
775943
hashCode:
775943
setsize:
1
hashCode:
776904
removestu1:
false
setsize:
1结果分析:
当我们将某个对象存到set中时,如果该对象的属性参与了hashcode的计算,那么以后就不能修改该对象参与hashcode计算的那些属性了,否则会引起意向不到的错误的。
正如测试中,不能够移除stu1对象。
总结:
1、equals方法用于比较对象的内容是否相等(覆盖以后)2、hashcode方法只有在集合中用到3、当覆盖了equals方法时,比较对象是否相等将通过覆盖后的equals方法进行比较(判断对象的内容是否相等)。
4、将对象放入到集合中时,首先判断要放入对象的hashcode值与集合中的任意一个元素的hashcode值是否相等,如果不相等直接将该对象放入集合中。
如果hashcode值相等,然后再通过equals方法判断要放入对象与集合中的任意一个对象是否相等,如果equals判断不相等,直接将该元素放入到集合中,否则不放入。
5、将元素放入集合的流程图:
6、HashSet中add方法源代码:
[java]viewplaincopypublicbooleanadd(Ee){returnmap.put(e,PRESENT)==null;}map.put源代码:
[java]viewplaincopy<prename="code"class="java">publicVput(Kkey,Vvalue){if(key==null)returnputForNullKey(value);inthash=hash(key.hashCode());inti=indexFor(hash,table.length);for(Entry<K,V>e=table[i];e!
=null;e=e.next){Objectk;if(e.hash==hash&&((k=e.key)==key||key.equals(k))){VoldValue=e.value;e.value=value;e.recordAccess(this);returnoldValue;}}modCount++;addEntry(hash,key,value,i);returnnull;}</pre><pre></pre><pre></pre>转自
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- hashCode equals 区别 联系 经典