很多时候,设计一个类,我们需要重写超类Object中的equals(Object o)、hashCode()以及toString()
- equals(Object o):比较当前对象与指定对象o的状态(比较两个对象中所有字段的值)是否相同,是即返回true,否则返回false
- hashCode():获得当前对象的散列码,超类Object中定义的hashCode()会将对象的存储地址作为散列码返回
- toString():为方便操作而存在,可用于打印对象的状态信息
那么,它们三儿具体应该怎么搞呢?
一、User类
-
定义一个用于测试的类User,包含两个字段以及对应的get/set方法
- - age:用户年龄,int类型
- - name:用户名字,String类型
class User{
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
二、重写equals(Object o)
-
设计步骤:
- 1. 用“==”判断对象o与当前对象是否为同一个对象,若是则直接返回true
- 2. 若对象o为null,则直接返回false
- 3. 根据情况选择使用getClass()方法或instanceOf关键字来判断对象o与当前对象是否为同一类型,若不是则返回false
- 4. 使用强制类型转换将对象o转化为当前对象类型
- 5. 依次判断对象o与当前对象中的所有对应字段是否相同,若全部相同则返回true
-
代码:
class User{
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@override
public boolean equals(Object o) {
if(this==o)return true;//1、用“==”判断对象o与当前对象是否为同一个对象,若是则直接返回true
if(o==null)return false;//2、 若对象o为null,则直接返回false
if(!(getClass()==o.getClass()))return false;//3、使用getClass()方法来判断对象o与当前对象是否为同一类型,若不是则返回false
User user=(User)o;//4、使用强制类型转换将对象o转化为当前对象类型User
return user.getAge()==age&&Objects.equals(name,user.getName());//5、依次判断对象o与当前对象中的所有对应字段是否相同,若全部相同则返回true
}
}
三、重写hashCode()
-
设计步骤:
- 1. 只要重写了equals()方法,则必须重写hashCode()
- 2. 当a.equals(b)返回true时,a.hashCode()==b.hashCode()也必须返回true
- 3. 一般直接将所有字段对应的散列码相加即可
- 4. 多数情况下会添加一个素数31,用于最大可能的保证散列码的唯一;当然31也可以换成7,11,13等(但一定是素数)。大多数人喜欢用31是因为hash*31可以被虚拟机优化为(hash<<5)-hash
-
代码:
class User{
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@override
public int hashCode() {
int hash=0;
int
hash=31*hash+Integer.hashCode(age);//31也可以换成7,11,13等(但一定是素数)。大多数人喜欢用31是因为hash*31可以被虚拟机优化为(hash<<5)-hash
hash=31*hash+Objects.hashCode(name);
return hash;
}
}
四、重写toString
-
toString()的设计就很简单了,一般都是自定义的格式。下面是java核心思想中推荐的格式来重写的toString():
-
代码:
class User{
private int age;
private String name;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@override
public String toString() {
return getClass().getName()+
"[name is:"+getName()+
",age is:"+getAge()+
"]";
}
}