一. 概览
public boolean equals(Object obj);
public native int hashcode();
public String toString();
protected void finalize() throws Throwable{}
protected native Object clone() throws CloneNotSupportedException
public final native Class<?> getClass()
public final native void notify()
public final native void notifyALL()
public final native void wait(long timeout) throws InterruptedException
public final void wait(long timeout, int nanos) throws InterruptedException
public final void wait() throws InterruptedException
二. equals()
1. 等价的条件
x.equals(x); //true -----------------------自反性
x.equals(y) == y.equals(x); //true --------对称性
if(x.equals(y) && y.equals(z))
x.equals(z); //true -------------------传递性
x.equals(y) == x.equals(y); //true---------一致性
x.equals(null); //flase
2. == 和 equals()
- 对于基本类型:==判断两个值是否相等,基本类型没有equals()方法
- 对于引用类型:==判断两个变量地址是否相等,equals()判断对象内容是否相同
Object类中定义的equals()和==作用相同,即比较地址,使用时需要手动重写equals()
public boolean equals(Object obj){
return(this == obj);
}
String、包装类、Date、File等默认重写了Object中的equals方法,使其比较对象内容是否相同
自定义类重写equals(),重写原则:比较两对象内容是否相同,举例如下
class User{
private String name;
private int age;
//重写equals()方法
public boolean equals(Object obj){
if(obj == this){
return true;
}
if(obj instanceof User){
User u = (User)obj;
return this.age == u.age && this.name.equals(u.name);
}
return false;
}
}
三. hashCode()
hashCode()返回哈希值,哈希值的计算具有随机性,不同对象可能计算出相同哈希值
- Object中的hashCode()返回对象的内存地址
- equals(未重写)的两个对象哈希值一定相等,但哈希值相等的两个对象不一定equals
- 自定义类重写equals()后必须重写hashCode(),保证等价的两个对象哈希值也相等
- HashSet和HashMap使用hashCode()计算对象存储位置,对应的类要实现hashCode()
问题1:为什么重写equals()后必须重写hashCode()?
判断对象是否相同时,先根据hashCode()进行判断
哈希值不同,则对象一定不同,哈希值相同,再根据equals()进行判断
下面的代码中,我们希望两个创建的对象是完全一样的,并将它们添加到HashSet(无序、不可重复)中,假设在EqualExample类中重写了equals()方法,而没重写hashCode()方法,equals()判断为true,调用Object中的hashCode()方法返回两个对象内存地址,所以哈希值不同,导致集合最终添加了两个等价的对象,违背了HashSet不可重复的原则
EqualExample e1 = new EqualExample(1, 1, 1);
EqualExample e2 = new EqualExample(1, 1, 1);
System.out.println(e1.equals(e2)); //true
HashSet<EqualExample> set = new HashSet<>();
set.add(e1);
set.add(e2);
System.out.println(set.size()); //2 导致重复添加
四. toString()
Object类中toString()的定义:
public String toString(){
return getclass().getname() + "@" + Integer.toHexString(hashCode());
// @后面的数值为散列码的无符号十六进制表示
}
- String、包装类、File、Date等已重写toString(),使调用后返回实际内容
- 当我们输出一个对象的引用时,实际上就是调用当前对象的toString()方法