本篇文章主要讲述 hashCode和equals方法 以及他们的重写,主要分以下几点进行讲述:
1、”==” 与 equals() 的区别
2、hashCode()和equals()的用法
“==” 与 equals() 的区别
java中的数据类型,可分为两类: 基本数据类型与符合数据类型
1、基本数据类型,。byte,short,char,int,long,float,double,boolean
他们之间的比较,应用双等号(==),比较的是他们的值。
2、复合数据类型(类)
当他们用(==)进行比较的时候,比较的是他们在内存中的存放地址,所以,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false。 JAVA当中所有的类都是继承于Object这个基类的,在Object中的基类中定义了一个equals的方法,这个方法的初始行为是比较对象的内存地 址,但在一些类库当中这个方法被覆盖掉了,如String,Integer,Date在这些类当中equals有其自身的实现,而不再是比较类在堆内存中的存放地址了。
使用hashCode()和equals()
hashCode()方法被用来获取给定对象的唯一整数。这个整数被用来确定对象被存储在HashTable类似的结构中的位置。默认的,Object类的hashCode()方法返回这个对象存储的内存地址的编号。
下面是一个 Student 类的实现:
public class Student
{
private Integer id;
private String firstname;
private String lastName;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getFirstname() {
return firstname;
}
public void setFirstname(String firstname) {
this.firstname = firstname;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
比较两个Student。
public class Test {
public static void main(String[] args) {
Student s1 = new Student();
Student s2 = new Student();
s1.setId(100);
s2.setId(100);
System.out.println(e1.equals(e2));
}
}
上面的程序将输出false,但是,事实上上面两个对象代表的是通过一个Student。真正的商业逻辑希望我们返回true。 为了达到这个目的,我们需要重写equals方法。
public boolean equals(Object o) {
if(o == null)
{
return false;
}
if (o == this)
{
return true;
}
if (getClass() != o.getClass())
{
return false;
}
Student e = (Student) o;
return (this.getId() == e.getId());
}
在上面的类中添加这个方法,Test将会输出true。考虑 Set 中的使用 :
public class EqualsTest{
public static void main(String[] args)
{
Student e1 = new Student();
Student e2 = new Student();
s1.setId(100);
s2.setId(100);
System.out.println(s1.equals(s2));
Set<Student> studentSet = new HashSet<Student>();
studentSet.add(s1);
studentSet.add(s2);
System.out.println(studentSet);
}
}
上面的程序输出的结果是两个。如果两个Student对象equals返回true,Set中应该只存储一个对象才对,问题在哪里呢? 我们忘掉了第二个重要的方法hashCode()。就像JDK的Javadoc中所说的一样,如果重写equals()方法必须要重写hashCode()方法。我们加上下面这个方法,程序将执行正确。
@Override
public int hashCode()
{
final int PRIME = 31;
int result = 1;
result = PRIME * result + getId();
return result;
}