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

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

Java 对象比较涉及基本数据类型、包装类、String 及自定义对象。基本类型用 == 比较值;包装类和 String 推荐 equals 比较内容,注意缓存池机制。自定义对象需重写 Object 的 equals 和 hashCode 方法判断逻辑相等,使用 HashSet/HashMap 时尤为重要。排序方面,实现 Comparable 接口定义自然排序,使用 Comparator 接口定义定制排序规则。掌握这些方法可确保集合去重、查找及业务逻辑的正确性。

数字游民发布于 2026/3/26更新于 2026/7/1230 浏览
Java 对象比较详解:基本类型与自定义类实现

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 方法有两种用法:

  1. 只传一个 List,此时 List 里的每个对象必须实现了 Comparable 接口,重写了 compareTo 方法,sort 方法会自动调用对象的 compareTo 来排顺序。
  2. 传一个 List 再加一个 Comparator 比较器,此时对象自己会不会比大小无所谓,sort 方法会用你传的比较器里的规则来排。
适用场景
  • 对象有固定的默认排序规则(如用户默认按 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 比较器。

Comparable 相当于让你的对象自己学会排序,而 Comparator 则是外部的排序工具,可以在不修改对象源码的情况下定义排序规则。

目录

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

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

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

更多推荐文章

查看全部
  • AI 时代产品经理:厘清 AI 能力边界与技术限制
  • 学术论文润色与降重:60 个 AI 大模型指令集
  • 宇树 Unitree 机器人 ROS 2 环境部署指南 (Humble + 真实硬件)
  • CentOS 系统定时执行 Python 邮件发送任务的五种方案
  • Vheer:免费免登录的 AI 绘画与视频生成工具
  • Edict 三省六部制 OpenClaw 集成封装版部署与使用
  • ImageNet 图像识别技术原理与应用
  • 网络通讯核心协议详解:TCP、UDP 与 HTTP/HTTPS
  • PostgreSQL 中文全文检索原理与实战:结合 jieba 分词实现高效搜索
  • AI 驱动游戏:鸿蒙生态的机会在哪里?
  • AI+AR智能眼镜赛道年终观察
  • C++ 测试与调试:从框架到工具链的实践备忘
  • Java 智慧养老系统:护理代办与陪诊全场景覆盖
  • 基于通义千问 LLM 实现本地简单多轮对话
  • GitHub 2026 年 AI 项目热度分析报告
  • Win7 本地编译 llama.cpp 部署 Qwen3 模型指南
  • VS Code 前端开发必备 10 款插件及配置教程
  • 使用 Trae AI 将设计稿自动生成前端代码指南
  • 2024年AI大模型时代C端应用生态变局与产业创新价值分析
  • 无人机远程路径规划技术:A*算法与GPS定位实现

相关免费在线工具

  • 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