java中进行相等判断时,“equals"和”==" 的使用场景和区别
public boolean equals(Object obj) 指示其他某个对象是否与传入的此对象“相等”。
equals 方法在非空对象引用上实现相等关系:
特性
自反性:对于任何非空引用值 x,x.equals(x) 都应返回 true。
对称性:对于任何非空引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true。
传递性:对于任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 应返回 true。
一致性:对于任何非空引用值 x 和 y,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上 equals 比较中所用的信息没有被修改。
对于任何非空引用值 x,x.equals(null) 都应返回 false。
Object 类的 equals 方法实现对象上差别可能性最大的相等关系;即,对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true(x == y 具有值 true)。
注意点
当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。
为什么重写hashCode方法,感兴趣可查看此篇博客,不过多解释
添加链接描述
代码测试练习
public boolean equals(Object o);
Object 定义该方法的目的 是为了 让所有的对象 可以和 其他的对象比较是否相等的。
而 Object 类的默认实现是:
public boolean equals(Object obj) {
return (this == obj);
}
比较的是当前对象和 传入的对象 是否是同一个对象。比较的是对象的地址。
如果子类有比较内容是否相等的需求,那么需要在自己的类中重写 equals 方法。
public class TestStudent {
public static void main(String[] args) {
//比较两个基本数据类型是否一样。 ==
int value1 = 10;
int value2 = 10;
System.out.println(value1 == value2);//true
//比较两个引用数据类型 比较两个学生是否一致
Student s1 = new Student("小黑", 17);
Student s2 = new Student();
//使用 == 比较两个对象是否一致。比较的是对象的地址是否一致。
System.out.println(s1 == s2);//
//如果我们希望两个对象的属性的信息是一致的,那么它俩就是相等。equals 方法就是用来比较内容的。
// Object 类 定义 equals 方法的目的,就是为了让对象和其他的对象进行内容的比较。
// 如果当前对象和 传入的对象的内容相等,那么就返回 true。否则返回 false。
Student s3 = new Student("小黑", 19);;
System.out.println();
System.out.println(s1.equals(s2));//true
System.out.println(s1.equals(s1));//true
System.out.println(s1.equals(null));//false
System.out.println(s1.equals("123"));//false
System.out.println(s1.equals(s3));//false
}
}
class Student{
private String name;
private int age;
public Student() {
this("小黑", 17);
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
String getName() {
return name;
}
void setName(String name) {
this.name = name;
}
int getAge() {
return age;
}
void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
@Override //注解 必须保证下面的方式为重写的父类中的某个方法,不然就报错。
public boolean equals(Object o){
//先考虑特殊情况
//如果 传入的 o 是 null
if(o == null)
return false;
// 如果 传入的 o 是 当前对象
if(this == o)
return true;
if(!(o instanceof Student))//o 不是Student 类型的对象。
return false;
//o 是一个学生
Student s = (Student)o;
if(this.age != s.age)
return false;
if(!this.name.equals(s.name))
return false;
return true;
}
}
结论
euqals :默认实现是 比较对象的地址。
如果某一个类的对象有比较对象的内容是否相等的需求,那么就有必要重写equals 方法
当对象的equals()方法被重写时,通常有必要重写 hashCode() 方法,以维护 hashCode 方法的常规协定,该协定声明相等 对象必须具有相等的哈希码。如下:
(1)两个对象相等,hashcode一定相等
(2)两个对象不等,hashcode不一定不等
(3)hashcode相等,两个对象不一定相等
(4)hashcode不等,两个对象一定不等
hashcode是用于散列数据的快速存取,如利用HashSet/HashMap/Hashtable类来存储数据时,都是根据存储对象的hashcode值来进行判断是否相同的。这样如果我们对一个对象重写了euqals,意思是只要对象的成员变量值都相等那么euqals就等于true,但 不重写hashcode,那么我们再new一个新的对象,当原对象.equals(新对象)等于true时,两者的hashcode却是不一样的,由此将产生了理解的不一致。