Java-EE-Object 通用方法-equals()

Java-EE-Object 通用方法-equals()

概览

在Java中,所有的类默认继承自java.lang.Object类,因此Object类中定义的方法对于Java中的所有对象都是可用的。以下是Object类的一些通用方法:

  1. equals(Object obj)
    • 检查两个对象是否相等。默认实现比较的是对象的内存地址,但通常需要重写以提供有意义的比较逻辑。
  2. toString()
    • 返回对象的字符串表示形式。默认实现返回对象的类名和哈希码的无符号十六进制表示,但通常需要重写以提供更有用的信息。
  3. hashCode()
    • 返回对象的哈希码值。根据equals方法的重写,通常也需要重写hashCode方法以保持一致性。
  4. getClass()
    • 返回对象的Class对象,该对象表示对象的运行时类。
  5. wait()wait(long timeout)wait(long timeout, int nanos)
    • 导致当前线程等待,直到另一个线程调用该对象的notify()notifyAll()方法,或者超过指定的时间。
  6. notify()
    • 唤醒在此对象监视器上等待的单个线程。
  7. notifyAll()
    • 唤醒在此对象监视器上等待的所有线程。
  8. clone()
    • 创建并返回对象的一个副本。默认实现会抛出CloneNotSupportedException,需要重写Cloneable接口并实现该方法。
  9. finalize()
    • 当垃圾回收器准备回收对象时调用此方法以进行清理。通常不推荐使用,因为Java 9开始已经过时。

这些方法为所有Java对象提供了基本的操作,很多方法在实际编程中都会根据需要被重写以实现特定的功能。例如,为了使对象能够正确地进行比较,通常会重写equalshashCode方法。同样,为了提供对象的可读性更好的字符串表示,会重写toString方法。

equals()

等价关系与实现

在Java中,equals()方法是一个在java.lang.Object类中定义的方法,用于检查两个对象是否相等。默认情况下,Object类的equals()方法实现是基于对象引用的比较,即它比较的是两个对象的内存地址是否相同。但是,对于需要根据对象内容来判断是否相等的情况,我们需要重写equals()方法。

以下是equals()方法的一些关键点:

  1. 重写equals()方法的规则
    • 自反性:对于任何非空引用xx.equals(x)应该返回true
    • 对称性:对于任何非空引用xyx.equals(y)应该等于y.equals(x)
    • 传递性:对于任何非空引用xyz,如果x.equals(y)返回true,且y.equals(z)返回true,那么x.equals(z)也应该返回true
    • 一致性:对于任何非空引用xy,只要equals比较中所用的信息没有被修改,多次调用x.equals(y)应该一致地返回true或一致地返回false
    • 与 null 的比较:对于任何非空引用xx.equals(null)应该返回false
  2. 为什么要重写equals()方法
    • 当对象的逻辑相等性不能通过比较内存地址来确定时,需要重写equals()方法。
  3. hashCode()方法的关系
    • 当重写equals()方法时,通常也需要重写hashCode()方法,以保持equals()hashCode()之间的一致性。如果两个对象通过equals()方法比较是相等的,那么这两个对象调用hashCode()方法也必须产生相同的整数值。
  4. 示例
public 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) {
        // 自反性
        if (this == obj) {
            return true;
        }
        // 检查是否为null
        if (obj == null) {
            return false;
        }
        // 检查是否是正确的类型
        if (getClass() != obj.getClass()) {
            return false;
        }
        // 强转并比较字段
        Person other = (Person) obj;
        return age == other.age && name.equals(other.name);
    }

    @Override
    public int hashCode() {
        // 根据对象的属性计算哈希码
        int result = 17;
        result = 31 * result + (name == null ? 0 : name.hashCode());
        result = 31 * result + age;
        return result;
    }
}

在这个例子中,Person类有两个属性:nameageequals()方法被重写,以确保当两个Person对象具有相同的nameage时,它们被认为是相等的。同时,hashCode()方法也被重写,以确保具有相同属性的Person对象产生相同的哈希码。

equals() 与 ==

在Java中,==运算符和equals()方法都用于比较两个对象,但它们在比较方式和用途上存在明显的区别:

  1. ==运算符

    • ==运算符用于比较两个对象的引用是否相等,即是否指向内存中的同一个对象。
    • 对于基本数据类型(如int、float、double等),==运算符比较的是值是否相等。
    • 对于对象,==运算符比较的是两个引用是否指向同一个对象实例。
  2. equals()方法

    • equals()方法是一个在Object类中定义的方法,用于比较两个对象的逻辑相等性,即比较对象的内容是否相等。
    • 默认情况下,equals()方法比较的是对象的内存地址,但通常需要重写这个方法以提供更有意义的比较逻辑。
    • 当重写equals()方法时,应该遵循非空性、等价性、对称性、传递性和一致性的原则。

区别

  • ==是一个运算符,而equals()是一个方法。
  • ==比较的是对象的引用,而equals()比较的是对象的逻辑相等性。
  • ==对于基本数据类型是比较值,对于对象是比较引用;equals()默认比较引用,但可以被重写以比较对象内容。
  • equals()方法可以被重写,以提供更复杂的比较逻辑,而==运算符不能被重写。

使用场景

  • 当需要比较两个变量是否引用同一个对象时,使用==运算符。
  • 当需要比较两个对象的内容是否相等时,使用equals()方法。

注意事项

  • 当重写equals()方法时,通常也需要重写hashCode()方法,以保持equals()hashCode()之间的一致性。这是因为很多数据结构(如HashMap、HashSet等)依赖于hashCode()方法来快速定位对象。

示例

String str1 = new String("hello");
String str2 = new String("hello");
String str3 = str1;

System.out.println(str1 == str2); // 输出 false,因为str1和str2是不同的对象
System.out.println(str1 == str3); // 输出 true,因为str3引用的是str1的对象
System.out.println(str1.equals(str2)); // 输出 true,因为str1和str2的内容相同

在这个例子中,str1str2是两个不同的对象,所以str1 == str2的结果是false。而str3引用的是str1的对象,所以str1 == str3的结果是true。尽管str1str2是不同的对象,但它们的内容相同,所以str1.equals(str2)的结果是true

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值