package cn.galc.test;
public class TestEquals {
public static void main(String[] args) {
/**
* 这里使用构造方法Cat()在堆内存里面new出了两只猫,
* 这两只猫的color,weight,height都是一样的,
* 但c1和c2却永远不会相等,这是因为c1和c2分别为堆内存里面两只猫的引用对象,
* 里面装着可以找到这两只猫的地址,但由于两只猫在堆内存里面存储在两个不同的空间里面,
* 所以c1和c2分别装着不同的地址,因此c1和c2永远不会相等。
*/
Cat c1 = new Cat(1, 1, 1);
Cat c2 = new Cat(1, 1, 1);
System.out.println("c1==c2的结果是:"+(c1==c2));//false
System.out.println("c1.equals(c2)的结果是:"+c1.equals(c2));//false
}
}
class Cat {
int color, weight, height;
public Cat(int color, int weight, int height) {
this.color = color;
this.weight = weight;
this.height = height;
}
}
画出内存分析图分析c1和c2比较的结果,当执行Cat c1 = new Cat(1,1,1); Cat c2 = new Cat(1,1,1);
之后内存之中布局如下图:
class Cat {
int color, weight, height;
public Cat(int color, int weight, int height) {
this.color = color;
this.weight = weight;
this.height = height;
}
/**
* 这里是重写相等从Object类继承下来的equals()方法,改变这个方法默认的实现,
* 通过我们自己定义的实现来判断决定两个对象在逻辑上是否相等。
* 这里我们定义如果两只猫的color,weight,height都相同,
* 那么我们就认为这两只猫在逻辑上是一模一样的,即这两只猫是“相等”的。
*/
public boolean equals(Object obj){
if (obj==null){
return false;
}
else{
/**
* instanceof是对象运算符。
* 对象运算符用来测定一个对象是否属于某个指定类或指定的子类的实例。
* 如果左边的对象是右边的类创建的对象,则运算结果为true,否则为false。
*/
if (obj instanceof Cat){
Cat c = (Cat)obj;
if (c.color==this.color && c.weight==this.weight && c.height==this.height){
return true;
}
}
}
return false;
}
}
设计思路很简单:先判断比较对象是否为null—>判断比较对象是否为要比较类的实例—–>比较俩个成员变量是否完全相等。
//另外一种常用重写方法
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null) return false;
if (getClass() != obj.getClass()) return false;
People other = (People) obj;
if (age != other.age) return false;
if (firstName == null) {
if (other.firstName != null) return false;
} else if (!firstName.equals(other.firstName)) return false;
if (lastName == null) {
if (other.lastName != null) return false;
} else if (!lastName.equals(other.lastName)) return false;
return true;
}
上面方法确实提高了效率。但一个面临问题:若两个对象equals相等,但不在一个区间,因为hashCode的值在重写之前是对内存地址计算得出,所以根本没有机会进行比较,会被认为是不同的对象。所以Java对于eqauls方法和hashCode方法是这样规定的: 1 如果两个对象相同,那么它们的hashCode值一定要相同。也告诉我们重写equals方法,一定要重写hashCode方法,也就是说hashCode值要和类中的成员变量挂上钩,对象相同–>成员变量相同—->hashCode值一定相同。 2 如果两个对象的hashCode相同,它们并不一定相同,这里的对象相同指的是用eqauls方法比较。