转载自:https://blog.csdn.net/zh_w_h163/article/details/11907869
在程序中,我们习惯使用equals方法来比较两个对象,继承自Object的equals方法默认的比较两个对象的内存地址(String类重写了equals方法,比较字符串的内容)。假如我们创建了两个Person对象,二者同名同姓,我们认为二者相同,但若是用equals方法比较二者,由于内存地址不同,返回的仍是false。因此我们需要重写equlas方法,以我们的视角来建立规则。我们以实例来分析:
我们创建一个类并重写其equals方法,并创建两个对象person1和person2对象,然后比较二者。
1.只重写equals方法:代码
1 /** 2 * 3 */ 4 package kklazy.test.equalsAndHashCode; 5 6 /** 7 * @author whh 8 * 9 */ 10 public class Person { 11 12 private String name; 13 private int age; 14 15 /** 16 * @return the name 17 */ 18 public String getName() { 19 return name; 20 } 21 /** 22 * @param name the name to set 23 */ 24 public void setName(String name) { 25 this.name = name; 26 } 27 /** 28 * @return the age 29 */ 30 public int getAge() { 31 return age; 32 } 33 /** 34 * @param age the age to set 35 */ 36 public void setAge(int age) { 37 this.age = age; 38 } 39 /* (non-Javadoc) 40 * @see java.lang.Object#hashCode() 41 */ 42 // @Override 43 // public int hashCode() { 44 // final int prime = 31;//只要为素数就可以 45 // int result = 1; 46 // result = prime * result + age; 47 // result = prime * result + ((name == null) ? 0 : name.hashCode()); 48 // return result; 49 // } 50 /* (non-Javadoc) 51 * @see java.lang.Object#equals(java.lang.Object) 52 */ 53 @Override 54 public boolean equals(Object obj) { 55 if (this == obj)// 如果二者引用的为同一个对象,则返回true 56 return true; 57 if (obj == null)// 如果比较的对象为null,返回false 58 return false; 59 if (getClass() != obj.getClass()) 60 return false; 61 Person other = (Person) obj; 62 if (age != other.age) 63 return false; 64 if (name == null) { 65 if (other.name != null) 66 return false; 67 } else if (!name.equals(other.name)) 68 return false; 69 return true; 70 } 71 72 73 74 }
通过Junit测试,并将两个对象存放到HashSet之中,代码如下:
1 /** 2 * 3 */ 4 package kklazy.test; 5 6 import java.util.HashSet; 7 import java.util.Set; 8 9 import org.junit.Test; 10 import org.junit.runner.RunWith; 11 import org.springframework.test.context.ContextConfiguration; 12 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 13 14 import kklazy.test.equalsAndHashCode.Person; 15 16 /** 17 * @author whh 18 * 19 */ 20 @RunWith(SpringJUnit4ClassRunner.class) 21 @ContextConfiguration(locations = { "classpath*:/beans/**/*.xml" }) 22 public class EqualsAndHashCodeJunitTest { 23 Set<Person> set = new HashSet<Person>(); 24 @Test 25 public void test(){ 26 Person person1=new Person(); 27 person1.setName("wang"); 28 person1.setAge(18); 29 Person person2=new Person(); 30 person2.setName("wang"); 31 person2.setAge(18); 32 System.out.println("返回结果:"+person1.equals(person2)); 33 set.add(person1); 34 set.add(person2); 35 System.out.println("set存在"+set.size()+"个对象 "+set); 36 } 37 38 }
结果如下所示:二者比较结果:trueset存在2个对象:[com.zhang.demo.Person@1ceebfa, com.zhang.demo.Person@1e6743e]
此时我们发现一个问题,虽然通过重写equals方法判断两个对象相等,但二者都存入到了set之中。纳尼?众所周知,set中只能存入不同的对象,显然对于HashSet来说,仅仅重写equals方法是不够的(对于HashMap也一样),通过了解集合比较对象的原理,我们才知道,原来集合先比较两个对象的HashCode是否相等,若相等,则通过equlas方法比较,若两个方法都通过,则两个对象被视为同一个对象。接下来,我们再将hashCode方法重写。
2.重写hashCode方法:把注释的hashCode方法代码放开
然后在通过以上的测试方法测试,结果如下:
二者比较结果:true
set存在1个对象:[com.zhang.demo.Person@d6168d67]
set存在1个对象:[com.zhang.demo.Person@d6168d67]
此时,HashSet之中只存入了一个对象。