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

Java 中对象的几种比较方式

Java 中对象比较的核心方法。基本元素比较涉及基本数据类型使用==,包装类和 String 优先使用 equals() 比较内容。自定义对象比较主要通过覆写 Object 的 equals() 和 hashCode() 判断相等性,通过实现 Comparable 接口定义自然排序,或使用 Comparator 接口实现定制排序。文章提供了各类比较方式的代码示例、核心规则及适用场景,帮助开发者根据实际需求选择合适的比较策略。

人间失格发布于 2026/3/30更新于 2026/10/2497 浏览
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   ;
System.out.println(i1 == i2); 
System.out.println(i1.equals(i2)); 

   ;
   ;
System.out.println(i3 == i4); 
System.out.println(i3.equals(i4)); 
i2
=
127
// true,在缓存范围内
// true
Integer
i3
=
128
Integer
i4
=
128
// false,超出缓存范围
// 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 版本中可能的改进

对象的比较

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 比较器。

Comparable 就是让你的对象自己学会排序,比如 User 类实现了它,就相当于 User 自己知道'我要按 id 排'。而 Comparator 呢,就是一个外部的排序小工具,你想让 User 按名字排,就做一个按名字比较的小工具传给排序方法,不用改 User 本身。一个是自带技能,一个是外部工具。

目录

  1. 引言
  2. 基本元素比较
  3. 1. 基本数据类型:直接用 == 比较值
  4. 2. 包装类:分两种情况
  5. 3. String 类型:核心看 == 和 equals() 的区别
  6. 基本元素比较的核心建议
  7. 总结
  8. 对象的比较
  9. 1. 覆写基类 Object 的 equals() + hashCode()
  10. 核心用途
  11. 核心规则
  12. 实现要点
  13. 示例
  14. 适用场景
  15. 2. 基于 Comparable 接口的比较
  16. 核心用途
  17. 核心方法
  18. 实现要点
  19. 示例
  20. 适用场景
  21. 3. 基于 Comparator 比较器的比较
  22. 核心用途
  23. 核心方法
  24. 实现形式
  25. 示例
  26. 适用场景
  27. 总结一下

更多推荐文章

查看全部
  • 利用 Ollama + RAGFlow 部署千问大模型构建个人知识库 AI 智能体
  • Cesium Shader 材质体系解析:从 Fabric 到渲染管线
  • OpenClaw 接入飞书机器人并部署 Ollama 本地大模型实战
  • WebPShop 插件:Photoshop 支持 WebP 格式指南
  • Flutter wasm_ffi 在鸿蒙端的适配与实战指南
  • Antigravity:谷歌推出的免费 AI 编程工具评测与使用指南
  • Flutter for OpenHarmony 实战:使用 money2 实现高精度金融计算
  • Windows 下配置 KDB+、JupyterQ 与 Python (embedPy) 环境
  • Python Pandas 高效读取 Excel 文件完整指南
  • 鸿蒙电商购物车项目:用户管理、商品列表与购物车实现
  • Seedance 2.0:AI 视频生成新范式与开发者上手指南
  • Python vs Scala:大数据预处理工具链深度评测
  • 8 个实用 jQuery 技巧
  • Python 语法核心速查:从基础到进阶实战
  • Clawbot 接入飞书与阿里云部署指南:打造 24 小时 AI 助理
  • 大模型基于 llama.cpp 量化详解
  • 动态规划专题:子序列问题深度解析
  • NewStar CTF Web 赛题解题思路汇总
  • 视觉语言模型(VLM)综述:训练、评估与扩展指南
  • Python 学习指南:基础语法、项目实战与职业路径

相关免费在线工具

  • 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

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online