Java零基础入门-Comparable vs Comparator
哈喽,各位小伙伴们好,我是喵手。
今天我要给大家分享一些自己日常学习到的一些知识点,并以文字的形式跟大家一起交流学习,互相学习,才能成长的更快,对吧。
我是一名java开发,所以日常接触到最多的就是java啦,所以我趁自己有空,就来好好回忆,把自己学到的会的,进行输出,不图什么有回报,只想能帮助到更多的小伙伴,就好。
小伙伴们在批阅的过程中,如果觉得文章不错,欢迎点赞、收藏、关注哦。三连即是对喵手我创作道路上最好的鼓励与支持!
一、前言
论前几期啊,我们是分别讲了Object类
、Date类
、FormDate类
、Calendar类
、System类
及StringBuilder类
,不知道大家掌握的如何,如果没有及时巩固的同学,可以看我这里,我给大家罗列了下,快速学习通道,只希望能帮助到大家更好的学习与成长,这就是我写作的初衷。
在前几期,我们是有讲过Collection类的,不知道大家还是否有印象,我们都知道,Collection分为两类,一类是单列集合,一类是双列集合。
而今天我们就来讲一期Collections工具集使用的下篇,(Collections其包位置:java.utils.Collections),它?与Collection类?不要误解,Collections是一集合工具类,用来对集合进行一系列操作的工具类。
二、Comparable
1️⃣概念:
上一期说起Collections所提供的sort()排序api,今天我就要给大家科普下了。Comparable和Comparator这两个接口了。
咱们先来聊聊Comparable吧,首先它是一个泛型接口。其次在Java类库中:Byte,Short,Integer,Long,Float,Double、及Date类等都有实现这Comparable接口,这些基本类型对象都可以直接调用实现了Comparable接口的compareTo()方法来进行排序。
比如如下Integer源码截图:
再比如如下的Date类源码截图:
具体使用:我就以Date()类来进行演示啦。
2️⃣演示:
演示代码如下:
3️⃣实例演示结果:
演示代码执行结果截图如下:
4️⃣总结:
Comparable强行对实现它的每个类的对象进行整体排序,像这种就是类的自然排序,compareTo()方法就被称为Comparable接口的自然比较方法。其方法只能在类中实现一次,不能经常修改类的代码从而实现自定义排序,局限还是比较大的。
像实现此接口的数组和集合,可以通过通过Collections.sort() 或Arrays.sort()进行自动排序,但你说要实现集合中的自定义的对象排序,就没法直接使用Collections.sort()方法了,编译期不知道按照什么规则来进行排序,直接使用肯定报错,这个时候你就得用到Comparable接口了。
因此Comparable常被称为内比较器。
5️⃣CompareTo()用法:
拓展:
int CompareTo(T object)
Java提供Comparable接口就是为了解决比较两个对象的问题。
其方法相对于比较对象的顺序,小于返回负整数,等于返回0,大于返回正整数。
三、Comparator
1️⃣概念:
上述是讲了Comparable接口,接下来就是Comparator。与上面讲的Comparable接口所不同的是:Comparator位于java.util包下,而Comparable位于java.lang包下;而且Comparable接口是将比较代码嵌入到需要进行比较的类的自身代码中,像我列举的Integer、Double等,它们都是直接实现了Comparable接口的CompareTo()方法,而Comparator接口不同,它的使用是在一个独立的类外进行实现比较的,不但提供了升序降序排序法,还不强制排序规则,可自定义指定排序规则,比如按年龄排序,按首字母排序等。
该接口定义如下:
2️⃣注意:
1、若一个类实现Comparator接口;它一定要实现compare(T o1, T o2) 方法,可以不实现 equals(Object obj) 方法。
2、其中int compare(T o1, T o2) 方法比较的是o1和o2的大小。若比较结果返回“负数”,表示o1比o2小;返回“零”,表示o1等于o2;返回“正数”,表示o1大于o2。
3️⃣Comparator使用场景:
- 若类已经实现Comparable接口,但是它提供的默认排序规则满足不了你的排序需求,你想根据自己的业务情况重新定义排序比较规则。那这时候你可以使用匿名内部类的方式来达到你比较的目的。
- 某个类你的手里只有字节码文件,无法拿到源代码,那不管这个类有没有实现Comparable接口,你就可以通过Comparator接口来达到比较的目的。
... ...
好啦,以上就是本期内容的全部教学内容啦,如果对文中的任何知识点有疑问,欢迎评论区评论留言呀,我看见都会一一解答的。
总的可以归纳如下:
1. Comparable
的概念
Comparable
接口位于 java.lang
包下,定义了一个用于比较对象的 compareTo
方法。该接口提供了一种自然排序的机制,让实现该接口的类的对象能够被自动排序。
public interface Comparable<T> {
int compareTo(T o);
}
- 泛型参数
T
:表示要比较的对象类型。 compareTo
方法:用于比较当前对象与指定对象的顺序。
2. Comparable
的实现
实现 Comparable
接口的类必须重写 compareTo
方法。这个方法返回一个整数,用于指示当前对象和传入对象的比较结果:
- 返回负整数:当前对象小于传入对象。
- 返回零:当前对象等于传入对象。
- 返回正整数:当前对象大于传入对象。
示例:
public class Student implements Comparable<Student> {
private String name;
private int score;
public Student(String name, int score) {
this.name = name;
this.score = score;
}
public int compareTo(Student other) {
return this.score - other.score; // 按分数升序排序
}
// 省略 getter 和 setter 方法
}
在这个例子中,Student
类实现了 Comparable
接口,compareTo
方法按照学生的分数进行升序排序。
3. Comparable
的应用场景
Comparable
接口主要用于以下场景:
- 自然排序:当你希望一个类的对象可以根据某种自然顺序排序时,比如数字、字母顺序、日期等。
- 集合排序:
Comparable
使得类的对象可以直接使用Collections.sort()
方法进行排序。 - 数组排序:实现了
Comparable
接口的类的对象可以通过Arrays.sort()
方法进行排序。
示例:
List<Student> students = new ArrayList<>();
students.add(new Student("Alice", 85));
students.add(new Student("Bob", 92));
students.add(new Student("Charlie", 78));
Collections.sort(students); // 按分数排序
for (Student student : students) {
System.out.println(student.getName() + ": " + student.getScore());
}
4. 注意事项
在使用 Comparable
接口时,需要注意以下几点:
- 不可修改排序逻辑:
compareTo
方法定义的排序逻辑一旦确定,就不容易在不修改类代码的情况下改变。如果你需要多种排序方式,可能需要考虑使用Comparator
接口。 - 一致性:
compareTo
方法的实现需要满足以下条件:- 自反性:
x.compareTo(x)
必须返回0
。 - 对称性:
x.compareTo(y)
与y.compareTo(x)
的符号相反。 - 传递性:
x.compareTo(y)
>0
且y.compareTo(z)
>0
,则x.compareTo(z)
>0
。
- 自反性:
- 与
equals
方法的关系:在大多数情况下,如果compareTo
返回0
,那么equals
方法也应该返回true
。虽然Comparable
不要求必须重写equals
方法,但为了保证排序的正确性,建议在实现compareTo
时考虑equals
的行为一致性。
如下是针对Comparable
的使用案例,分享给大家:
为了更好地理解 Comparable
接口的应用,我们通过一个具体的案例来展示如何实现和使用 Comparable
接口。这个案例将涉及创建一个 Student
类,按照学生的分数进行自然排序。
1. 定义 Student
类并实现 Comparable
接口
首先,我们定义一个 Student
类,并让它实现 Comparable<Student>
接口。我们将按照学生的分数 (score
) 对 Student
对象进行排序。
public class Student implements Comparable<Student> {
private String name;
private int score;
public Student(String name, int score) {
this.name = name;
this.score = score;
}
// Getter 和 Setter 方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
// 重写 compareTo 方法,根据 score 进行排序
public int compareTo(Student other) {
return this.score - other.score;
}
public String toString() {
return "Student{name='" + name + "', score=" + score + "}";
}
}
在这个 Student
类中,我们重写了 compareTo
方法,根据 score
进行升序排序。
2. 创建 Student
对象并进行排序
接下来,我们将创建多个 Student
对象,并将它们存储在一个 List
中。然后使用 Collections.sort()
方法对这些对象进行排序。
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ComparableExample {
public static void main(String[] args) {
// 创建多个 Student 对象
List<Student> students = new ArrayList<>();
students.add(new Student("Alice", 85));
students.add(new Student("Bob", 92));
students.add(new Student("Charlie", 78));
students.add(new Student("David", 88));
// 输出排序前的列表
System.out.println("排序前:");
for (Student student : students) {
System.out.println(student);
}
// 对 Student 对象进行排序
Collections.sort(students);
// 输出排序后的列表
System.out.println("\n排序后:");
for (Student student : students) {
System.out.println(student);
}
}
}
3. 运行结果
运行上面的代码后,你将看到 Student
对象按分数从低到高排序的结果。
排序前:
Student{name='Alice', score=85}
Student{name='Bob', score=92}
Student{name='Charlie', score=78}
Student{name='David', score=88}
排序后:
Student{name='Charlie', score=78}
Student{name='Alice', score=85}
Student{name='David', score=88}
Student{name='Bob', score=92}
4. 说明
- 在排序前,学生对象的顺序是按照添加的顺序排列的。
- 使用
Collections.sort()
方法后,学生对象按照分数的升序排列。 compareTo
方法的实现决定了排序的逻辑。这里我们是根据score
进行排序。如果想要实现其他排序方式,比如按姓名排序,可以修改compareTo
方法的实现。
5. 扩展:降序排序
如果想要实现降序排序,只需修改 compareTo
方法,改变返回值的符号即可:
public int compareTo(Student other) {
return other.score - this.score; // 改为降序排序
}
使用这个修改后的 compareTo
方法,学生将按分数从高到低排序。
四、小结
在这篇文章中,我们深入探讨了 `Comparable` 和 `Comparator` 两个接口在 Java 中的应用。通过具体的代码示例和实际操作,我们清晰地了解了 `Comparable` 接口是如何让类实现自然排序的,同时也明白了 `Comparator` 接口如何为我们提供灵活的自定义排序规则。通过这些内容,相信大家对排序机制有了更深的理解,并能在实际项目中更好地运用这些知识。
`Comparable` 接口提供了一个自然的比较方式,适用于需要整体排序的类,而 `Comparator` 则为我们提供了更大的灵活性,可以根据具体业务需求自定义排序规则。它们在 Java 集合框架中都扮演了不可或缺的角色,帮助我们高效地处理数据。
五、总结
通过本期的学习,大家应该对 `Comparable` 和 `Comparator` 两个接口有了更加深入的认识。`Comparable` 强调的是类的自然排序,而 `Comparator` 则更关注于提供灵活的比较方式,适用于更多复杂场景的排序需求。在编码实践中,这两个接口各有千秋,使用得当可以让代码更加简洁、可维护。
**学习之路漫漫,唯有不断积累才能不断进步。** 希望小伙伴们能通过这篇文章掌握更多 Java 的核心知识,并在日常开发中多加实践。正如我一直所倡导的,分享知识,互相学习,才能一起成长。愿我们在编程的道路上携手并进,共同迈向更加光明的未来。
如果你对文中的内容有任何疑问或想法,欢迎在评论区留言,我们一起探讨,共同成长!记得点赞、收藏、关注喵手哦,这将是对我继续分享的最大支持与鼓励!
六、文末
教学是结束了,但是有些话不知我但讲不当讲,啊哈哈, 可我还是想说给你们听听。如下是我很喜欢的一句话,我打算送给你们,希望我们都能变得更好更优秀。
学习不分先后,知识不分多少;事无巨细,当以虚心求教;三人行,必有我师焉!!!
wished for you successed !!!
-------------------------------------------
⭐️若喜欢我,就请关注我叭。
⭐️若对您有用,就请点赞叭。
⭐️若有疑问,就请评论留言告诉我叭。
-------------------------------------------
- 点赞
- 收藏
- 关注作者
评论(0)