资讯动态

Java排序总报错?Comparable和Comparator区别一文搞懂

发布时间:2026/8/25 14:23:07 来源:尧图企业网站定制
文章目录一、先搞懂一个问题为什么排序会报错二、Comparable对象自己会比较三、Comparator找个裁判来比较四、核心区别五、最容易混淆的点compare和equals六、整体逻辑梳理铁汁们当技术变化越来越快把基础打牢才是最稳的捷径。一起加油假如遇到过这种情况写了一个Student类new了一堆对象塞进数组调用 Arrays.sort() 想排个序结果程序直接抛异常。一、先搞懂一个问题为什么排序会报错Java 的 Arrays.sort() 方法本身很强大能给 int、String 等基本类型和常见类型排序。但当你传入一个自定义对象数组时JDK 就懵了。它不知道两个Student对象到底谁大谁小——是按年龄比按姓名比还是按学号比没有比较规则sort就无法工作。核心结论自定义对象要排序必须先告诉 JDK “怎么比”。Java提供了两种方式来定义比较规则让对象自己具备比较能力→Comparable接口内部比较器外部传入一个裁判来比较 →Comparator接口外部比较器)二、Comparable对象自己会比较核心思想把比较逻辑写在实体类内部让对象本身拥有比较能力。就像每个人自带一把尺子自己就能和别人比身高。怎么用三步走第一步实体类实现 Comparable泛型 接口第二步重写 compareTo() 方法• this 代表当前对象入参是待对比的另一个对象• 返回 int 值负数 → 当前对象排前面正数 → 参数对象排前面0 → 视为相等第三步直接调用 Arrays.sort(数组)只传数组一个参数代码示例classStudentimplementsComparableStudent{Stringname;intage;OverridepublicintcompareTo(Studento){returnthis.age-o.age;// 按年龄升序}}//调用Student[]arr{...};Arrays.sort(arr);优缺点✅优点调用简单sort 时只传数组即可❌弊端排序规则写死在实体类里想换一种排序方式必须修改实体类源码⚠️ 踩坑提醒没有实现 Comparable 就直接 sort会抛出 ClassCastException三、Comparator找个裁判来比较核心思想不改动原有实体类代码单独创建外部比较器充当裁判。就像跑步比赛运动员不用自己带尺子场边有裁判负责计时排名。怎么用三步走第一步实体类不用实现任何接口原有代码保持不变第二步创建裁判类实现Comparator泛型重写compare(o1, o2)方法• 两个都是入参没有 this 关键字• 返回值规则和compareTo一样负 → o1 在前正 → o2 在前0 → 相等第三步调用 Arrays.sort(数组, 裁判对象)传入数组 比较器两个参数代码示例//裁判按年龄升序classAgeCmpimplementsComparatorStudent{Overridepublicintcompare(Students1,Students2){returns1.age-s2.age;}}//调用Student[]arr{...};Arrays.sort(arr,newAgeCmp());优势✅ 实体类零改动符合开闭原则✅ 切换排序逻辑只需要新建一个比较器无需修改实体源码✅ 一个实体类可以对应多种排序规则按年龄、按姓名、按学号……四、核心区别对比维度Comparable 内部比较器Comparator 外部比较器比较规则位置写在实体类内部单独写在外面裁判类核心方法compareTo(o)1个参数有thiscompare(o1,o2)2个参数无thissort调用方式sort(arr)sort(arr,比较器对象)修改排序规则需要改动实体类源码新建比较器即可不动原类排序规则数量一个类只能有一种默认规则可以有任意多种规则设计模式对象自带行为策略模式行为可插拔五、最容易混淆的点compare和equals很多初学者会把compare和equals搞混其实它们完全是两回事compareTo()/compare()→返回int用于排序判断对象的大小先后顺序equals()→返回boolean只判断对象是否相等不能用来排序举个例子两个学生年龄相同compare 返回 0排序时视为同级但 equals 可能返回 false他们不是同一个人。记住排序用compare判等用equals各司其职。六、整体逻辑梳理自定义对象数组调用sort排序 → JDK不知道对象如何对比大小方案1赋予对象自身比较能力 → Comparable 内部比较器sort“学生A你去跟学生B比一下告诉我结果”方案2传入外部裁判做对比 → Comparator 外部比较器sort“裁判把学生A和B拿过去比一比告诉我结果”每天进步一点点铁汁们一起加油预告我们用 Arrays.sort 完成了Student数组排序。但要留意排序是直接改动原数组调换的只是对象的地址不会新建Student对象。很多人会想那我复制一份新数组拿新数组排序原数组不就安全了实际这么做会踩坑复制出来的数组和原数组共用同一批学生对象。下一篇就讲浅拷贝和深拷贝把这个坑讲明白。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价