== 和 equals() 的区别 -Java

在Java中,==equals() 是两个常用的比较操作符,它们用来比较对象,但它们的工作原理和适用场景有显著的不同。

1. == 运算符

== 是一个比较操作符,主要用于:

  • 基本数据类型的比较:它比较的是两个变量存储的值是否相等。
  • 对象的引用比较:它比较的是两个对象的引用(即内存地址)是否相同,即判断两个引用是否指向同一个对象。

基本数据类型的比较

对于基本数据类型(如intfloatchar等),==比较的是它们存储的实际值。

代码示例:

public class EqualOperatorExample {
    public static void main(String[] args) {
        int a = 10;
        int b = 10;
        
        System.out.println(a == b);  // true, 比较的是值,10 == 10
    }
}

对象引用的比较

对于对象,== 比较的是对象的引用地址,即判断两个对象是否是同一个对象。

代码示例:

public class EqualOperatorExample {
    public static void main(String[] args) {
        String str1 = new String("Hello");
        String str2 = new String("Hello");

        // 比较对象的引用地址,str1 和 str2 并不是同一个对象
        System.out.println(str1 == str2);  // false
    }
}

说明:

  • str1 == str2 返回 false,因为str1str2指向的是两个不同的对象,虽然它们的内容一样,但它们在内存中的地址不同。
  • == 只是比较对象的引用地址,而不是内容。

2. equals() 方法

equals()Object 类中定义的方法,用于比较两个对象的内容是否相同。大多数类(例如 StringInteger 等)会重写该方法,以便按对象的实际内容进行比较。

默认实现

默认情况下,equals() 方法比较的是对象的引用地址(即与 == 相同)。但许多类(如 StringList 等)重写了该方法,以便比较对象的内容而不是引用地址。

示例:String 类重写了 equals() 方法

String 类中,equals() 被重写为比较字符串内容是否相同。

代码示例:

public class EqualsMethodExample {
    public static void main(String[] args) {
        String str1 = new String("Hello");
        String str2 = new String("Hello");

        // 比较字符串的内容
        System.out.println(str1.equals(str2));  // true
    }
}

说明:

  • str1.equals(str2) 返回 true,因为 String 类重写了 equals() 方法,它会比较字符串的内容,而不是它们的引用地址。

3. 总结比较:==equals()

比较方式 == 运算符 equals() 方法
用途 比较基本数据类型的值,或者对象的引用地址 比较对象的内容(通过 equals() 重写时)
基本数据类型 比较值是否相等 不适用,基本类型不能调用 equals() 方法
对象 比较引用是否指向同一个对象 比较对象的内容(需类重写 equals() 方法)
默认行为 默认比较引用地址(对象的内存位置) 默认比较引用地址,除非类重写该方法进行内容比较
适用场景 适用于基本数据类型和对象引用比较 适用于对象的内容比较(字符串、集合等)

4. equals() 方法的重写

对于自定义类,如果希望 equals() 方法比较对象的内容而不是引用地址,需要重写 equals() 方法。常见的重写 equals() 方法的步骤如下:

  1. 使用 instanceof 检查类型:确保比较的对象类型相同。
  2. 比较属性:逐一比较对象的关键属性。

代码示例:

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;
        
        // 判断是否是同类型的对象
        if (obj == null || getClass() != obj.getClass()) return false;
        
        // 强制转换为 Person 对象
        Person person = (Person) obj;
        
        // 比较两个 Person 对象的属性
        return name.equals(person.name) && age == person.age;
    }
}

public class EqualsMethodOverrideExample {
    public static void main(String[] args) {
        Person person1 = new Person("Alice", 25);
        Person person2 = new Person("Alice", 25);
        
        // 通过重写的 equals() 方法比较对象内容
        System.out.println(person1.equals(person2));  // true
    }
}

说明:

  • equals() 方法首先判断是否为同一个对象,如果是,直接返回 true
  • 然后判断是否是相同类型的对象,再逐一比较每个属性,最后返回比较结果。

5. hashCode()equals() 的关系

在Java中,equals()hashCode() 方法是相互关联的。根据 Java 的合同规则,如果两个对象通过 equals() 方法比较相等,那么它们的 hashCode() 也必须相等。否则,可能会导致集合(如 HashMapHashSet)中的问题。

  • 如果两个对象相等(equals()true),那么它们的 hashCode() 必须相同。
  • 如果两个对象的 hashCode() 相同,并不一定意味着它们相等。

6. 总结

  • == 比较基本数据类型的值,或者对象的引用地址。
  • equals() 比较对象的内容,通常需要重写,尤其是在自定义类中。
  • 通过重写 equals() 方法,可以根据对象的实际内容来比较对象。
Java碎碎念 文章被收录于专栏

来一杯咖啡,聊聊Java的碎碎念呀

全部评论
mark
点赞 回复 分享
发布于 02-23 00:43 广东

相关推荐

核心本地商业-业务研发平台4月9日1:面试官自我介绍+自我介绍2:Spring源码讲一下3:Spring源码学完什么收获4:spring的事务了解吗?,mysql的事务呢?5:spring的事务和mysql的事务有什么联系?6:项目jdk什么版本?7:默认垃圾回收器是什么?8:介绍一下ZGC和G1?9:项目性能调优怎么做的?垃圾回收器参数,jvm参数,10:Seata分布式事务?11:其他分布式事务了解吗?(模模糊糊说了MQ)12:AT和TCC说一下?13:看过12306官方的实现吗?14:既然你看过一些实现,那么你想怎么优化呢?(答了锁粒度方案,和redis方案)15:redis方案的一致性怎么解决?(答了cannal,MQ)16:redis网络波动,用于以为下单失败,但是其实redis收到消息怎么办?(当时说的MQ,但是面试官想说的不是这个,后面复盘应该是本地消息表+定时任务)17: 项目数据库方面有什么优化?(联合索引,explan,慢查询日志,skywalking)18:加完索引,前端需要注意什么?19:数据库的什么字段适合加索引 ,什么字段不适合? 20:Hashmap源码看过吗21:Hashmap多个线程put有什么问题?(值覆盖,极端情况下数组越界)22:值覆盖举个例子?23:极端情况下数组越界什么意思?24:还有其他的情况吗?(最后答了链表和红黑树可能会空指针异常)25:多线程用什么替代?(concurentHashmap)26:concurentHashmap1.7和1.8区别?27:concurentHashmap1.7为什么用了CAS?28:concurentHashmap1.8怎么实现?(乐观和悲观两种情况)29:1.8里的volatile是什么?30:volatile能解决线程安全问题吗?(不能)31:那能解决什么问题?32:SQL题,单表topk,审错题意了,写了快20分钟用子查询才写出来,然后面试官说有没有其他方法,又写了10分钟33:大模型相关问题,agent,Transfomer34:反问全称1小时40分钟,汗流浃背,后面写SQL的时候脑子已经不转了。二面4月15日1:深挖项目(20分钟)2:Redission怎么实现的?3:为什么不用redis的setnx?4:数据库分库分表,分库分表会有什么问题?(说了一下怎么分库分表,有什么问题没打上来)5:某个服务器cpu飙高怎么排查(top,htop,ps, jstake, dump文件,visualVM)6:优化sql?(skywalking,慢查询日志,索引,elplain的字段)7:深度分页优化?(业务上不允许深度分页,子查询,索引查询,游标分页)反问#牛客AI配图神器#二面完,感觉g了,面试官说项目没选好,mysql没有分库,不太像分布式项目。
这名字响亮不响亮:我去,spring是你简历写的熟悉源码嘛,还是面试官直接问的嗷。好可怕
点赞 评论 收藏
分享
评论
4
1
分享

创作者周榜

更多
牛客网
牛客企业服务