从equals方法开始说

一句废话,eqauls方法是用来判断对象是否相等的。
怎么判断的呢?可以重写类的equals方法,在equals方法中实现判等逻辑。
但是没有重写equals方法,怎么判断两个对象是否相等呢?根据java的继承机制,咱们去找它爸爸,去看看父类是怎么实现的equals方法。类的老祖宗Ojbect中,equals方法实现十分简单,如下:

1
2
3
4
5
6
7
8
9
10
/**
* @param obj the reference object with which to compare.
* @return <code>true</code> if this object is the same as the obj
* argument; <code>false</code> otherwise.
* @see #hashCode()
* @see java.util.Hashtable
*/
public boolean equals(Object obj) {
return (this == obj);
}

通俗易懂,就是判断两个对象地址是否相等。
看下面一例:
定义student类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
public class Student {
/**
* 学号
*/
private String stu_no;
/**
* 姓名
*/
private String name;
public Student() {
}
public Student(String no, String name) {
this.stu_no = no;
this.name = name;
}
public String getStu_no() {
return stu_no;
}
public void setStu_no(String stu_no) {
this.stu_no = stu_no;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
} else if (null == obj) {
return false;
} else if (!(obj instanceof Student)) {
return false;
} else if (this.name.equals(((Student) obj).getName())
&& this.stu_no.equals(((Student) obj).getStu_no())) {
return true;
}
return false;
}
}

执行测试类:

1
2
3
4
5
6
7
8
9
public static void main(String[] args) {
Set<Student> set = new HashSet<Student>();
Student stu1 = new Student("1", "张三");
set.add(stu1);
Student stu2 = new Student("1", "张三");
set.add(stu2);
System.out.println("是否equal:" + stu1.equals(stu2));
System.out.println("set大小:" + set.size());
}

结果输出:
是否equal:true
set大小:2
为啥set里放进了两个equal的对象;答:因为hashCode不同;
对呀,还有hashCode这回事;
先来说明为什么set中放入了两个equal的对象;因为在向set中添加数据的时候先检查两个对象的hashCode是否相等,如果不等的话,会直接将对i想放入到集合中。如果两个对象的hashCode相等时,才会去调用equals方法判断是否相等;
那为什么没有重写hashCode方法,他们的hashCode值就不同能。再到父类中去寻找hashCode的实现。

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* As much as is reasonably practical, the hashCode method defined by
* class <tt>Object</tt> does return distinct integers for distinct
* objects. (This is typically implemented by converting the internal
* address of the object into an integer, but this implementation
* technique is not required by the
* Java<font size="-2"><sup>TM</sup></font> programming language.)
*
* @return a hash code value for this object.
* @see java.lang.Object#equals(java.lang.Object)
* @see java.util.Hashtable
*/
public native int hashCode();

可以看到这是调用一个本地方法;在注释中发现Object的hashCode会对每个对象返回唯一的hash值。
so,在没有重写hashCode方法的时候两个Student的hash值肯定是不同的。所以两个对象都可以放到set中。
那么什么情况下要重写equals方法和hashCode方法呢?

骐骏 wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!
坚持原创技术分享,您的支持将鼓励我继续创作!