==equals 方法在比较对象时的区别

1. == 运算符

  • 基本数据类型:对于基本数据类型(如 intchardouble 等),== 比较的是它们的值是否相等。例如:
int a = 5;
int b = 5;
System.out.println(a == b); // 输出: true
  • 引用数据类型:对于引用数据类型(如类、数组等),== 比较的是两个引用是否指向同一个对象,即它们在内存中的地址是否相同。例如:
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println(str1 == str2); // 输出: false,因为 str1 和 str2 指向不同的对象

2. equals 方法

  • equals 方法是 Object 类的一个实例方法,在 Object 类中,equals 方法的默认实现和 == 一样,比较的是两个对象的引用是否相等。Object 类中 equals 方法的定义如下:
public boolean equals(Object obj) {
    return (this == obj);
}
  • 许多类(如 StringInteger 等)重写了 equals 方法,使其用于比较对象的内容是否相等。例如:
String str1 = new String("hello");
String str2 = new String("hello");
System.out.println(str1.equals(str2)); // 输出: true,因为 String 类重写了 equals 方法,比较的是字符串内容

在自定义类中正确重写 equals 方法

在自定义类中重写 equals 方法时,需要遵循以下几个原则:

  • 自反性:对于任何非空引用值 xx.equals(x) 应该返回 true
  • 对称性:对于任何非空引用值 xy,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应该返回 true
  • 传递性:对于任何非空引用值 xyz,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 也应该返回 true
  • 一致性:对于任何非空引用值 xy,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上 equals 比较中所用的信息没有被修改。
  • 非空性:对于任何非空引用值 xx.equals(null) 应该返回 false

以下是一个自定义类重写 equals 方法的示例:

class Person {
    private String name;
    private int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public boolean equals(Object obj) {
        // 1. 检查是否为同一个引用
        if (this == obj) {
            return true;
        }
        // 2. 检查是否为 null
        if (obj == null) {
            return false;
        }
        // 3. 检查是否为同一类型
        if (getClass() != obj.getClass()) {
            return false;
        }
        // 4. 强制类型转换
        Person other = (Person) obj;
        // 5. 比较对象的属性
        return age == other.age && (name == null ? other.name == null : name.equals(other.name));
    }
}

public class Main {
    public static void main(String[] args) {
        Person p1 = new Person("Alice", 20);
        Person p2 = new Person("Alice", 20);
        System.out.println(p1.equals(p2)); // 输出: true
    }
}

在上述示例中,Person 类重写了 equals 方法,首先检查两个对象是否为同一个引用,然后检查对象是否为 null,接着检查对象是否为同一类型,最后比较对象的属性是否相等。