一、介绍Comparable
Interface Comparable是java.lang里的一个接口。此接口可用来给实现它的类的对象排序。
P.S. 一般使用Collections.sort或Arrays.sort排序。
二、使用Comparable
使用Arrays的sort方法可以对元素类型是基本类型的数组进行排序,而对元素类型是类类型的数组就无能为力了。譬如:对于一个学生数组,数组中元素的类型是Student类型的,若要先按学生的班级进行排序,在班级相同的情况下,再按学号进行排序。要实现这些的话,需要对学生类实现Comparable接口。
Comparable接口中声明了compareTo方法,其参数是该类的另一对象,在实现该方法时,需要指定按哪个数据成员进行比较(要求该成员已经实现了compareTo方法)。方法中传入一个对象,将对象和元素自身进行比较,如果元素自身大,返回1,相等返回0,元素自身小于参数则返回-1.
import java.util.Arrays;
public class ComparableTest {
public static void main(String[] args) {
Student students[] = new Student[4];
students[0] = new Student("A1502", "150202", "张三");
students[1] = new Student("C1501", "150101", "李四");
students[2] = new Student("A1501", "150102", "王五");
students[3] = new Student("B1502", "150201", "马六");
Arrays.sort(students);
for (int i = 0; i < students.length; i++) {
System.out.println(students[i]);
}
}
}
//Student类实现Comparable接口
class Student implements Comparable<Student> {
private String gradeName;
private String studentId;
private String studentName;
// 先根据班级排序,然后根据学号排序
public int compareTo(Student anotherStudent) {
if (gradeName.compareTo(anotherStudent.getGradeName()) != 0)
return gradeName.compareTo(anotherStudent.getGradeName());
else
return studentId.compareTo(anotherStudent.getStudentId());
} //String类已实现compareTo方法
public Student(String gradeName, String studentId, String studentName) {
this.studentId = studentId;
this.studentName = studentName;
this.gradeName = gradeName;
}
public String getGradeName() {
return gradeName;
}
public void setGradeName(String gradeName) {
this.gradeName = gradeName;
}
public String getStudentId() {
return studentId;
}
public void setStudentId(String studentId) {
this.studentId = studentId;
}
public String getStudentName() {
return studentName;
}
public void setStudentName(String studentName) {
this.studentName = studentName;
}
public String toString() {
return gradeName + "-" + studentId + "-" + studentName;
}
}
P.S. 如果上面重写的compareTo方法中,处理的是数字类型,例如如果要按年龄排序,那么需要如下操作:
private static class Student implements Comparable {
String name;
String id;
int age;
@Override
public int compareTo(Object o) {
return this.age - ((Student) o).age;
}
}
注意:
- Comparable接口里面有一个泛型T,T的选择为可以与之比较的对象的类型,一般就是实现该接口类的本身,可以这样想和Student类比较的当然是Student本身了。
下面是comparable的文档,有兴趣的话可以看一看:
Comparable (Java Platform SE 7 )
https://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html
一、介绍Comparator
Interface Comparator是java.util的一个接口。
可以将Comparator传递给Collections.sort或Arrays.sort,来实现精确控制排序顺序。
二、使用Comparator
上一个例子通过实现Student类的Comparable接口,为Student的数组指定了一个排序规则,即指定了排序的主关键字、次关键字。在实际应用中可能需要指定多种排序规则,如可以按学号排序,也可以按姓名排序。这个时候就需要提供多个比较器来完成要求了。
编写比较器类需实现Comparator接口。且有几种排序规则就需要定义几个比较器类,每个类分别实现Comparator接口,接口中包含compare方法,该方法有2个参数,分别是带比较的两个对象,方法的返回值是整型。
定义好了比较器之后,就可以使用Arrays的sort方法进行对象排序了。sort方法的格式如下:
public static <T> void sort(T[] arr, Comparator<? super T> obj)
我们可以这样使用:
import java.util.Arrays;
import java.util.Comparator;
import example1.Student; //导入上一个例子的Student类
public class ComparatorTest {
public static void main(String[] args) {
Student students[] = new Student[4];
students[0] = new Student("A1502", "150202", "张三");
students[1] = new Student("C1501", "150101", "李四");
students[2] = new Student("A1501", "150102", "王五");
students[3] = new Student("B1502", "150101", "马六");
System.out.println("--------原始学生信息如下:");
for (int i = 0; i < students.length; i++) {
System.out.println(students[i]);
}
Arrays.sort(students, new IdComparator());
System.out.println("--------根据学号排序后如下:");
for (int i = 0; i < students.length; i++) {
System.out.println(students[i]);
}
Arrays.sort(students, new NameComparator());
System.out.println("--------根据姓名排序后如下:");
for (int i = 0; i < students.length; i++) {
System.out.println(students[i]);
}
}
}
class IdComparator implements Comparator<Student> {
public int compare(Student s1, Student s2) {
int n = s1.getClassName().compareTo(s2.getClassName());
if (n == 0) {
return s1.getStudentId().compareTo(s2.getStudentId());
} else { return n;
}
}
}
class NameComparator implements Comparator<Student> {
public int compare(Student s1, Student s2) {
return s1.getStudentName().compareTo(s2.getStudentName());
}
}