一. Comparable接口
1.Comparable简介
Comparable排序接口
若一个类实现了Comparable的接口,就意味着该类支持排序
实现Comparable接口的类的对象的列表或数组可以通过Collections.sort或Arrays.sort进行自动排序。
Comparable接口的源码
public interface Comparable<T> {
public int compareTo(T o);
}
2. 为什么要实现Comparable接口
一个类可以实现Comparable接口,说明这个类具有可排序的功能或者说标准,两个对象通过Compareable接口中的compareTo方法的返回值来比较大小。
定义一个字符串数组将其排序后输出
import java.util.Arrays;
public class Test {
public static void main(String[] args) {
String[] str = {"xin","abc","rong","def"};
Arrays.sort(str);
System.out.println(Arrays.toString(str));
}
}
3. Comparable的实际应用
理解了Comparable接口后再来实现 给对象数组排序
让 Student 类实现 Comparable 接口, 并实现其中的 compareTo 方法
在 sort 方法中会自动调用 compareTo 方法, compareTo 的参数是 Object , 其实传入的就是 Student 类型的对象.
然后比较当前对象和参数对象的大小关系(按年龄来算). 如果当前对象应排在参数对象之前, 返回大于 0 的数字; 如果当前对象应排在参数对象之后, 返回小于于 0 的数字; 如果当前对象和参数对象不分先后, 返回 0; 再次执行程序, 结果就符合预期了
import java.util.Arrays;
class Student implements Comparable<Student>{
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Student o) {
if (this.age == o.age){
return 0;
}else if (this.age < o.age){
return -1;
}else {
return 1;
}
}
}
public class Test {
public static void main(String[] args) {
Student[] stu = {
new Student("zhansan",18),
new Student("lisi", 20),
new Student("zhaoliu",15)
};
Arrays.sort(stu);
System.out.println(Arrays.toString(stu));
}
}
注意事项:
对于 sort 方法来说, 需要传入的数组的每个对象都是 “可比较” 的, 需要具备 compareTo 这样的能力,通 过重写 compareTo 方法的方式, 就可以定义比较规则
这里自己实现一个 sort 方法来完成排序过程(使用冒泡排序)
public static void bubbleSort(Comparable[] array) {
for (int i = 0; i < array.length-1; i++) {
for (int j = 0; j < array.length-1-i; j++) {
if(array[j].compareTo(array[j+1]) > 0) {
Comparable tmp = array[j];
array[j] = array[j+1];
array[j+1] = tmp;
}
}
}
}
Comparator接口
1. Comparator简介
Comparator是比较接口,我们如果需要控制某个类的次序,而该类本身不支持排序(即没有实现Comparable接口),那么我们就可以建立一个“该类的比较器”来进行排序,这个“比较器”只需要实现Comparator接口即可。也就是说,我们可以通过实现Comparator来新建一个比较器,然后通过这个比较器对类进行排序。
Comparator接口源码:
public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);
}
2. Comparator接口的实际运用
Arrays.sort()中有下面给出的重载,可以用来排序自定义类型
- Arrays.sort(T[] a, Comparator<? super T> c);
下面分别以以对象的name和age属性定义俩个比较器,分别以这两个比较器去实现排序
在以name进行比较时,实际上是以字符串进行比较,String类实现了Comparable接口,所以可以直接调用comparTo方法。
import java.util.Arrays;
import java.util.Comparator;
class AgeComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o1.getAge() - o2.getAge();
}
}
class NameComparator implements Comparator<Student> {
@Override
public int compare(Student o1, Student o2) {
return o1.getName().compareTo(o2.getName());
}
}
class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
public class Test {
public static void main(String[] args) {
Student[] stu = {
new Student("ghi",18),
new Student("def", 15),
new Student("abc",20)
};
System.out.println("以年龄进行排序");
Arrays.sort(stu, new AgeComparator());
System.out.println(Arrays.toString(stu));
System.out.println("再以姓名进行排序");
Arrays.sort(stu, new NameComparator());
System.out.println(Arrays.toString(stu));
}
}
下面的代码是使用比较器比较对象
public class Test {
public static void main(String[] args) {
Student student1 = new Student("xin",10);
Student student2 = new Student("rong",40);
AgeComparator ageComparator = new AgeComparator();
if(ageComparator.compare(student1,student2) > 0) {
System.out.println("student1 > student2");
}else if(ageComparator.compare(student1,student2) == 0){
System.out.println("student1 = student2");
}else{
System.out.println("student1 < student2");
}
}
三. Comparable和Comparator的比较
Comparable是排序接口,若一个类实现了Comparable接口,就意味着“该类支持排序”;而Comparator是比较器,我们若需要控制某个类的次序,可以建立一个“该类的比较器”来进行排序。
比较器的作用:基本数据类型可以用sort();方法排序,但是引用数据类型不能用sort()排序或者比较大小得到我们想要的答案,就出现了比较器
Comparable相当于“内部比较器”
特点:
- 适用于两个对象的大小
- 在一个类里面完成
Comparator相当于“外部比较器”。
特点: - 适用于多个对象的比较、排序
- 层次清晰,简单易懂
Comparable 对类的侵入性非常强, 一但投入使用便不方便再做修改,用起来比较简单,只要实现Comparable 接口的对象直接就成为一个可以比较的对象,需要重写comparTo方法,所以如果想要更换比较方式,就需要对comparTo “大动干戈”。
直接在所创建的类中就行比较
Comparator 对类的侵入性比较弱, 使用起来非常灵活,用Comparator实现一个比较器, 当某个自定义的对象需要作比较的时候,把比较器和对象一起传递过去就可以比大小了, 使用Comparator比较,如果想要更换比较方式,只需要在原来的基础上再增加一个比较器即可。
又创建了一个比较类,把需要比较的类放进比较类中比较。