跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
Javajava

Java 对象比较详解:基本类型与自定义类实现

Java 对象比较涉及基本数据类型、包装类、String 及自定义类的处理。基本类型使用==比较值;包装类和 String 推荐使用 equals() 比较内容以避免缓存池导致的地址差异。自定义对象需重写 Object 的 equals() 和 hashCode() 方法以实现逻辑相等判断,常用于集合去重。排序方面,Comparable 接口定义自然排序规则,Comparator 接口提供灵活的外部定制排序方案。开发中应根据场景选择合适的方式确保数据一致性与正确性。

漫步发布于 2026/3/21更新于 2026/8/2342 浏览
Java 对象比较详解:基本类型与自定义类实现

引言

对象比较是 Java 编程中基础且核心的能力,它直接关系到集合元素的查找、排序、去重,以及业务逻辑中对象相等性的判断,是保证程序逻辑正确性和数据一致性的关键环节。

基本元素比较

Java 中基本元素(基本数据类型 + 对应的包装类 + 常用引用类型如 String)的比较规则,可以总结为以下核心要点:

1. 基本数据类型:直接用 == 比较值

Java 的 8 种基本数据类型(byte、short、int、long、float、double、char、boolean),只能用 == 比较值是否相等,不存在 equals() 方法。

int a = 10;
int b = 10;
System.out.println(a == b); // true,值相等
  • 注意:不同基本类型比较时会发生自动类型提升,比如 int 和 long 比较,int 会提升为 long 后再比。

2. 包装类:分两种情况

包装类(Integer、Long、Boolean 等)是引用类型,但有常量池缓存机制,比较规则需区分场景:

比较方式适用场景规则说明
==缓存范围内的包装类对象对于 Integer(-128 ~ 127)、Boolean(true/false)等,缓存池内的对象用 == 会返回 true
==缓存范围外的包装类对象会创建新对象,== 比较的是地址,返回 false
equals()所有包装类对象比较的是底层基本类型的值,推荐使用

示例:

Integer i1 = 127;
Integer i2 = 127;
System.out.println(i1 == i2); // true,在缓存范围内
System.out.println(i1.equals(i2)); // true

Integer i3 = 128;
Integer i4 = 128;
System.out.println(i3 == i4); // false,超出缓存范围
System.out.println(i3.equals(i4)); // true

3. String 类型:核心看 == 和 equals() 的区别

String 是引用类型,且有字符串常量池,比较规则是 Java 面试高频考点:

  • ==:比较的是对象的内存地址
    • 直接赋值的字符串(如 String s = "abc")会存入常量池,相同内容的字符串指向同一个地址。
    • new 创建的字符串(如 String s = new String("abc"))会在堆中创建新对象,地址不同。
  • equals():重写过的方法,比较的是字符串的内容,推荐使用。

示例:

String s1 = "hello";
String s2 = "hello";
String s3 = new String("hello");
System.out.println(s1 == s2); // true,常量池同一对象
System.out.println(s1 == s3); // false,地址不同
System.out.println(s1.equals(s3)); // true,内容相同
基本元素比较的核心建议
  1. 基本数据类型:直接用 == 即可。
  2. 包装类和 String:优先用 equals() 比较内容,避免因缓存/常量池机制导致的逻辑错误。

包装类和基本类型混合比较:包装类会自动拆箱为基本类型,用 == 直接比的值。

Integer i = 10;
int j = 10;
System.out.println(i == j); // true,i 自动拆箱为 int

对象的比较

Java 中自定义对象的比较,核心围绕 内容相等性判断 和 大小关系排序 两大需求,对应四种实现方式,其中前三种是开发中最常用的:

1. 覆写基类 Object 的 equals() + hashCode()

核心用途

判断两个对象的内容是否相等,是集合去重、条件判断的基础。

核心规则
  • equals():默认比较对象地址(==),需重写为基于核心业务属性(如用户 ID、订单号)的比较逻辑。
  • hashCode():必须和 equals() 保持一致(规范要求:equals 相等的对象,hashCode 必须相同),否则 HashSet/HashMap 等哈希集合会失效。
实现要点
  1. 自反性:x.equals(x) 必须返回 true。
  2. 对称性:x.equals(y) 和 y.equals(x) 结果一致。
  3. 传递性:x.equals(y) 且 y.equals(z),则 x.equals(z)。
  4. 一致性:对象属性不变时,多次调用 equals 结果不变。
  5. 非空性:x.equals(null) 必须返回 false。
示例
public class User {
    private Long id;
    private String name;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        User user = (User) o;
        return Objects.equals(id, user.id) && Objects.equals(name, user.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name);
    }
}
适用场景
  • 判断两个对象是否为'逻辑相等'(如判断两个用户是否是同一个人)。
  • 作为 HashSet 元素、HashMap 的 key 时的必要操作。

2. 基于 Comparable 接口的比较

核心用途

定义对象的自然排序规则(默认排序规则),让对象'天生可比较'。

核心方法

实现 int compareTo(T o) 方法:

  • 返回 正数:当前对象 > 目标对象。
  • 返回 0:当前对象 = 目标对象。
  • 返回 负数:当前对象 < 目标对象。
实现要点
  • 排序规则基于业务核心属性(如按用户 ID 升序、按价格降序)。
  • 需满足比较器一致性:x.compareTo(y) == 0 应和 x.equals(y) 结果一致(非强制,但推荐遵守)。
示例
public class User implements Comparable<User> {
    private Long id;
    private String name;

    // 按 id 升序排序
    @Override
    public int compareTo(User o) {
        return this.id.compareTo(o.id);
    }
}

public class UserNameLengthComparator implements Comparator<User> {
    @Override
    public int compare(User u1, User u2) {
        // 比较两个 User 对象名字的长度
        int len1 = u1.getName().length();
        int len2 = u2.getName().length();
        // 按名字长度升序排列,如果想降序就反过来减
        return len1 - len2;
    }
}

// 然后,当你需要排序的时候,比如对一个 List<User>进行排序,就可以把这个 Comparator 传进去:
List<User> userList = new ArrayList<>();
// 假设已经往 userList 里加了一些 User 对象
Collections.sort(userList, new UserNameLengthComparator());
  • Collections.sort 方法有两种用法。第一种,只传一个 List,这时候 List 里的每个对象,必须自己会'比大小',也就是实现了 Comparable 接口,重写了 compareTo 方法。sort 方法会自动调用对象的 compareTo 来排顺序。第二种,传一个 List 再加一个 Comparator 比较器,这时候对象自己会不会比大小无所谓,sort 方法会用你传的比较器里的规则来排。简单说就是,不传比较器,就用对象自己的 compareTo;传了比较器,就听比较器的。
适用场景
  • 对象有固定的默认排序规则(如用户默认按 ID 排序、商品默认按价格排序)。
  • 用于 Collections.sort(List)、TreeSet/TreeMap 的默认排序。

3. 基于 Comparator 比较器的比较

核心用途

定义对象的定制排序规则,灵活扩展多种排序方式,不修改对象本身代码。

核心方法

实现 int compare(T o1, T o2) 方法,规则和 compareTo 一致。

实现形式
  • 匿名内部类。
  • Lambda 表达式(JDK 8+ 推荐)。
  • 静态工具类(如 Comparator.comparing)。
示例
// 方式 1:Lambda 表达式,按姓名长度降序
Comparator<User> nameLengthComparator = (u1, u2) -> Integer.compare(u2.getName().length(), u1.getName().length());

// 方式 2:工具类,按姓名升序
Comparator<User> nameComparator = Comparator.comparing(User::getName);
适用场景
  • 对象需要多种排序规则(如用户可按 ID、姓名、注册时间排序)。
  • 无法修改对象源码(如第三方类),但需要排序。
  • 用于 Collections.sort(List, Comparator)、TreeSet 构造函数指定排序规则。

总结一下

比较方式核心作用灵活性适用场景
equals() + hashCode()判断内容相等低集合去重、逻辑相等判断
Comparable自然排序(默认规则)低对象有固定排序规则
Comparator定制排序(多规则)高多种排序需求、第三方类排序
Objects.compare简化比较 + 空指针防护中JDK 8+ 简洁排序代码

选型口诀:

  • 判相等:重写 equals + hashCode。
  • 单排序:实现 Comparable。
  • 多排序:用 Comparator 比较器。

目录

  1. 引言
  2. 基本元素比较
  3. 1. 基本数据类型:直接用 == 比较值
  4. 2. 包装类:分两种情况
  5. 3. String 类型:核心看 == 和 equals() 的区别
  6. 基本元素比较的核心建议
  7. 对象的比较
  8. 1. 覆写基类 Object 的 equals() + hashCode()
  9. 核心用途
  10. 核心规则
  11. 实现要点
  12. 示例
  13. 适用场景
  14. 2. 基于 Comparable 接口的比较
  15. 核心用途
  16. 核心方法
  17. 实现要点
  18. 示例
  19. 适用场景
  20. 3. 基于 Comparator 比较器的比较
  21. 核心用途
  22. 核心方法
  23. 实现形式
  24. 示例
  25. 适用场景
  26. 总结一下
  • 免费图片AI生成工具免费生成了解详情
  • Magick API 一键接入全球大模型注册送1000万token查看
  • 免费图片视频在线生成30秒,将你的创意变成现实开始设计
  • X/Twitter免费视频下载器免登陆无限额度免费视频解析下载了解详情
  • 100+免费在线小游戏爽一把
极客日志微信公众号二维码

微信扫一扫,关注极客日志

微信公众号「极客日志V2」,在微信中扫描左侧二维码关注。展示文案:极客日志V2 zeeklog

更多推荐文章

查看全部
  • Python 第三方库实战:键盘监听与学生管理系统
  • .NET WebApi 项目必要配置项详解
  • 666 条数据训练 AI 写万字长文,模型数据集开源
  • Openclaw 结合飞书的多机器人配置指南
  • GitHub 代码下载失败问题解决方案
  • Linux 信号处理流程与操作系统中断机制解析
  • AMD Whisper 实战:大规模语音转文本推理效率优化
  • 大模型落地路线图研究报告(2024 年)
  • 基于 Java 的百度地图路线规划服务开发
  • KiCad 符号编辑器引脚添加与同步机制解析
  • 前端 Canvas 技术详解:绘图、动画与数据可视化
  • OpenClaw 接入飞书机器人并集成 Ollama 本地大模型实战
  • LLM 驱动的智能体(Agent)应用与实践指南
  • 大模型面试核心知识点与参考答案
  • Python 核心应用场景与开发环境配置指南
  • mssql1069错误(由于登录失败而无法启动服务)解决方法
  • 基于 Trae 与 CMake 构建 AI 辅助的 Qt 开发环境
  • Android 编程权威指南:深入理解 Intent 与任务机制(一)
  • Moon VR Video Player 评测:支持 8K/12K 多音轨与外挂字幕
  • Chrome 插件开发指南:从 Web 到扩展及实战

相关免费在线工具

  • Keycode 信息

    查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online

  • Escape 与 Native 编解码

    JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online

  • JavaScript / HTML 格式化

    使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online

  • JavaScript 压缩与混淆

    Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online