首页
首页 教程 派聪明
  • 首页
  • 教程
  • 派聪明
  • 登录
登录技术派畅享更多权益

用户名密码登录

其他登录:
icon_GitHubCreated with sketchtool.
绑定星球,畅享VIP服务

微信扫码/长按识别登录

输入验证码
有效期五分钟 👉 手动刷新

登录即同意 用户协议 和 隐私政策

绑定二哥编程星球,畅享 VIP 尊享服务!

戳我了解如何获取星球编号,新窗口打开

添加二哥微信 itwanger 审核更快

记得备注 星球编号
我会根据星球编号进行审核
1
教程简介
更新时间: 2023年02月22日
限免
2
Java简介,什么是 Java?
更新时间: 2023年02月22日
限免
3
安装Java开发工具包JDK
更新时间: 2023年02月22日
限免
4
安装集成开发环境Intellij IDEA
更新时间: 2023年02月22日
限免
5
编写第一个Java程序:Hello World
更新时间: 2023年02月22日
限免
6
关键字和保留字
更新时间: 2023年04月23日
限免
7
Java 注释
更新时间: 2023年04月23日
限免
8
Java 数据类型
更新时间: 2023年04月24日
限免
9
Java 数据类型转换
更新时间: 2023年04月24日
限免
10
Java 基本数据类型缓存池
更新时间: 2023年04月24日
限免
11
Java 运算符
更新时间: 2023年04月24日
限免
12
Java 流程控制语句
更新时间: 2023年04月24日
限免
13
掌握 Java 数组
更新时间: 2023年04月25日
限免
14
掌握 Java 二维数组
更新时间: 2023年04月25日
限免
15
打印 Java 数组
更新时间: 2023年04月25日
限免
16
解读 String 源码
更新时间: 2023年04月25日
限免
17
String 为什么不可变
更新时间: 2023年04月25日
限免
18
深入理解 Java 字符串常量池
更新时间: 2023年04月25日
限免
19
详解 String.intern 方法
更新时间: 2023年04月25日
限免
20
StringBuilder 和 StringBuffer
更新时间: 2023年04月25日
限免
21
判断字符串相等
更新时间: 2023年04月25日
限免
22
字符串拼接
更新时间: 2023年04月25日
限免
23
字符串拆分
更新时间: 2023年04月25日
限免
关注公众号
原创
字符串相等判断:Java中的equals()与==的区别与用法

4.9 String相等判断

“二哥,如何比较两个字符串相等啊?”三妹问。

“这个问题看似简单,却在 Stack Overflow 上有超过 370 万+的访问量。”我说,“这个问题也可以引申为 .equals() 和 ‘==’ 操作符有什么区别。”

  • “==”操作符用于比较两个对象的地址是否相等。
  • .equals() 方法用于比较两个对象的内容是否相等。

“不是很理解。”三妹感到很困惑。

“我来举个不恰当又很恰当的例子,一看你就明白了,三妹。”

有一对双胞胎,姐姐叫阿丽塔,妹妹叫洛丽塔。我们普通人可能完全无法分辨谁是姐姐谁是妹妹,可她们的妈妈却可以轻而易举地辨认出。

.equals() 就好像我们普通人,看见阿丽塔以为是洛丽塔,看见洛丽塔以为是阿丽塔,看起来一样就觉得她们是同一个人;“==”操作符就好像她们的妈妈,要求更严格,观察更细致,一眼就能分辨出谁是姐姐谁是妹妹。

String alita = new String("小萝莉");
String luolita = new String("小萝莉");

System.out.println(alita.equals(luolita)); // true
System.out.println(alita == luolita); // false

就上面这段代码来说,.equals() 输出的结果为 true,而“==”操作符输出的结果为 false——前者要求内容相等就可以,后者要求必须是同一个对象。

“三妹,之前已经学过了,Java 的所有类都默认地继承 Object 这个超类,该类有一个名为 .equals() 的方法。”一边说,我一边打开了 Object 类的源码。

public boolean equals(Object obj) {
    return (this == obj);
}

你看,Object 类的 .equals() 方法默认采用的是“==”操作符进行比较。假如子类没有重写该方法的话,那么“==”操作符和 .equals() 方法的功效就完全一样——比较两个对象的内存地址是否相等。

但实际情况中,有不少类重写了 .equals() 方法,因为比较内存地址的要求比较严格,不太符合现实中所有的场景需求。拿 String 类来说,我们在比较字符串的时候,的确只想判断它们俩的内容是相等的就可以了,并不想比较它们俩是不是同一个对象。

况且,字符串有字符串常量池的概念,本身就推荐使用 String s = "字符串" 这种形式来创建字符串对象,而不是通过 new 关键字的方式,因为可以把字符串缓存在字符串常量池中,方便下次使用,不用遇到 new 就在堆上开辟一块新的空间。

“哦,我明白了。”三妹说。

“那就来看一下 String 类的 .equals() 方法的源码吧。”我说。

public boolean equals(Object anObject) {
    if (this == anObject) {
        return true;
    }
    if (anObject instanceof String) {
        String aString = (String)anObject;
        if (coder() == aString.coder()) {
            return isLatin1() ? StringLatin1.equals(value, aString.value)
                    : StringUTF16.equals(value, aString.value);
        }
    }
    return false;
}

首先,如果两个字符串对象的可以“==”,那就直接返回 true 了,因为这种情况下,字符串内容是必然相等的。否则就按照字符编码进行比较,分为 UTF16 和 Latin1,差别不是很大,就拿 Latin1 的来说吧。

@HotSpotIntrinsicCandidate
public static boolean equals(byte[] value, byte[] other) {
    if (value.length == other.length) {
        for (int i = 0; i < value.length; i++) {
            if (value[i] != other[i]) {
                return false;
            }
        }
        return true;
    }
    return false;
}

这个 JDK 版本是 Java 17,也就是最新的 LTS(长期支持)版本。该版本中,String 类使用字节数组实现的,所以比较两个字符串的内容是否相等时,可以先比较字节数组的长度是否相等,不相等就直接返回 false;否则就遍历两个字符串的字节数组,只有有一个字节不相等,就返回 false。

这是 Java 8 中的 equals 方法源码:

public boolean equals(Object anObject) {
    // 判断是否为同一对象
    if (this == anObject) {
        return true;
    }
    // 判断对象是否为 String 类型
    if (anObject instanceof String) {
        String anotherString = (String)anObject;
        int n = value.length;
        // 判断字符串长度是否相等
        if (n == anotherString.value.length) {
            char v1[] = value;
            char v2[] = anotherString.value;
            int i = 0;
            // 判断每个字符是否相等
            while (n-- != 0) {
                if (v1[i] != v2[i])
                    return false;
                i++;
            }
            return true;
        }
    }
    return false;
}

JDK 8 比 JDK 17 更容易懂一些:首先判断两个对象是否为同一个对象,如果是,则返回 true。接着,判断对象是否为 String 类型,如果不是,则返回 false。如

登录之后即可阅读全文
该文档仅「二哥编程星球」的VIP用户可见

二哥的编程星球内容包括:

1. 付费文档: 技术派、MYDB 等项目配套的 120+篇教程查看权限

2. 面试指南: 校招、社招的 40 万+字面试求职攻略

3. 智能助手: 无限期使用派聪明 AI 助手,已对接讯飞星火和 ChatGPT双通道,不用花 1 分钱

4. 专属问答: 向二哥 1v1 发起提问,内容不限于 offer 选择、学习路线、职业规划等

5. 简历修改: 提供简历修改服务,附赠星球 100+优质简历模板可供参考

6. 学习环境: 打造一个沉浸式的学习环境,有一种高考冲刺、大学考研的氛围


二哥的星球

》步骤①:微信扫描上方二维码,点击「加入知识星球」按钮

》步骤②:访问星球置顶帖球友必看: https://t.zsxq.com/11rEo9Pdu,获取项目配套文档的语雀访问地址和密码

已加入星球,绑定星球编号
删除提醒

确定删除《字符串相等判断:Java中的equals()与==的区别与用法》吗

真诚点赞 诚不我欺

回复