读书人

hashCode与equals的差别与联系

发布时间: 2012-10-09 10:21:45 作者: rapoo

hashCode与equals的区别与联系

一、equals方法的作用

?? 1、默认情况(没有覆盖equals方法)下equals方法都是调用Object类的equals方法,而Object的equals方法主要用于判断对象的内存地址引用是不是同一个地址(是不是同一个对象)。

2 、要是类中覆盖了equals方法,那么就要根据具体的代码来确定equals方法的作用了,覆盖后一般都是通过对象的内容是否相等来判断对象是否相等。

没有覆盖equals方法代码如下:

view plain

??? //学生类?
??? public class Student {?
??????? private int age;?
??????? private String name;?
?????????
??????? public Student() {?
??????? }?
??????? public Student(int age, String name) {?
??????????? super();?
??????????? this.age = age;?
??????????? this.name = name;?
??????? }?
??????? public int getAge() {?
??????????? return age;?
??????? }?
??????? public String getName() {?
??????????? return name;?
??????? }?
??????? public void setAge(int age) {?
??????????? this.age = age;?
??????? }?
??????? public void setName(String name) {?
??????????? this.name = name;?
??????? }?
??? }?

测试 代码如下:

view plain

??? import java.util.HashSet;?
??? import java.util.LinkedList;?
??? import java.util.Set;?
?????
?????
??? public class EqualsTest {?
??????? public static void main(String[] args) {?
??????????? LinkedList<Student> list = new LinkedList<Student>();?
??????????? Set<Student> set = new HashSet<Student>();?
??????????? Student stu1? = new Student(3,"张三");?
??????????? Student stu2? = new Student(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("list size:"+ list.size());?
?????????????
??????????? set.add(stu1);?
??????????? set.add(stu2);?
??????????? System.out.println("set size:"+ set.size());?
??????? }?
?????
??? }?


运行结果:
stu1 == stu2 : false
stu1.equals(stu2) : false
list size:2
set size:2

结果分析:Student类没有覆盖equals方法,stu1调用equals方法实际上调用的是Object的equals方法。所以采用对象内存地址是否相等来判断对象是否相等。因为是两个新对象所以对象的内存地址不相等,所以stu1.equals(stu2) 是false。

3、我们覆盖一下equals方法(age和name属性),让Student类其通过判断对象的内容是否相等来确定对象是否相等。

覆盖后的Student类:

view plain

??? //学生类?
??? public class Student {?
??????? private int age;?
??????? private String name;?
?????????
??????? public Student() {?
??????? }?
??????? public Student(int age, String name) {?
??????????? super();?
??????????? this.age = age;?
??????????? this.name = name;?
??????? }?
??????? public int getAge() {?
??????????? return age;?
??????? }?
??????? public String getName() {?
??????????? return name;?
??????? }?
??????? public void setAge(int age) {?
??????????? this.age = age;?
??????? }?
??????? public void setName(String name) {?
??????????? this.name = name;?
??????? }?
??????? @Override?
??????? public boolean equals(Object obj) {?
??????????? if (this == obj)?
??????????????? return true;?
??????????? if (obj == null)?
??????????????? return false;?
??????????? if (getClass() != obj.getClass())?
??????????????? return false;?
??????????? Student other = (Student) obj;?
??????????? if (age != other.age)?
??????????????? return false;?
??????????? if (name == null) {?
??????????????? if (other.name != null)?
??????????????????? return false;?
??????????? } else if (!name.equals(other.name))?
??????????????? return false;?
??????????? return true;?
??????? }?
?????????
??? }?


运行结果:

stu1 == stu2 : false
stu1.equals(stu2) : true
list size:2
set size:2

结果分析:因为Student两个对象的age和name属性相等,而且又是通过覆盖equals方法来判断的,所示stu1.equals(stu2) 为true。注意以上几次测试list和set的size都是2

二、HashCode

4、通过以上的代码运行,我们知道equals方法已经生效。接下来我们在覆盖一下hashCode方法(通过age和name属性来生成hashcode)并不覆盖equals方法,其中Hash码是通过age和name生成的。

覆盖hashcode后的Student类:

view plain

??? //学生类?
??? public class Student {?
??????? private int age;?
??????? private String name;?
?????????
??????? public Student() {?
??????? }?
??????? public Student(int age, String name) {?
??????????? super();?
??????????? this.age = age;?
??????????? this.name = name;?
??????? }?
??????? public int getAge() {?
??????????? return age;?
??????? }?
??????? public String getName() {?
??????????? return name;?
??????? }?
??????? public void setAge(int age) {?
??????????? this.age = age;?
??????? }?
??????? public void setName(String name) {?
??????????? this.name = name;?
??????? }?
??????? @Override?
??????? public int hashCode() {?
??????????? final int prime = 31;?
??????????? int result = 1;?
??????????? result = prime * result + age;?
??????????? result = prime * result + ((name == null) ? 0 : name.hashCode());?
??????????? return result;?
??????? }????
??? }?


运行结果:

stu1 == stu2 : false
stu1.equals(stu2) : false
list size:2
hashCode :775943
hashCode :775943
set size:2

结果分析:我们并没有覆盖equals方法只覆盖了hashCode方法,两个对象虽然hashCode一样,但在将stu1和stu2放入set集合时由于equals方法比较的两个对象是false,所以就没有在比较两个对象的hashcode值。

5、我们覆盖一下equals方法和hashCode方法。

Student代码如下:

view plain

??? <pre name="code" class="java"> public V put(K key, V value) {?
??????????? if (key == null)?
??????????????? return putForNullKey(value);?
??????????? int hash = hash(key.hashCode());?
??????????? int i = indexFor(hash, table.length);?
??????????? for (Entry<K,V> e = table[i]; e != null; e = e.next) {?
??????????????? Object k;?
??????????????? if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {?
??????????????????? V oldValue = e.value;?
??????????????????? e.value = value;?
??????????????????? e.recordAccess(this);?
??????????????????? return oldValue;?
??????????????? }?
??????????? }?
?????
??????????? modCount++;?
??????????? addEntry(hash, key, value, i);?
??????????? return null;?
??????? }?

读书人网 >编程

热点推荐