一、概述
Comparable和Comparator在java中都是用于来比较数据大小。实现Comparable接口需要重写compareTo方法,实现Comparator方法需要重写compare方法。 这两个方法返回值都是int类型,根据返回值来判断比较对象的大小,从而实现排序。
二、Comparable 接口比较
1、Comparable接口位于java.lang.Comparable
2、定义一个 Student 学生类,如下:
/**
* description: 定义Student 学生类
* @version v1.0
* @author w
* @date 2019年10月31日下午10:10:34
**/
public class Student {
private String name ; // 姓名
private int age ; // 年龄
private double score ; // 分数
// ignore getter , setter
public Student(String name, int age, double score) {
super();
this.name = name;
this.age = age;
this.score = score;
}
public Student() {
super();
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", score=" + score + "]";
}
}
3、定义 StudentCompareable类,继承Student , 实现 Comparable接口,重写CompareTo方法。
/**
* description: StudentCompareable类,继承Student , 实现 Comparable接口,重写CompareTo方
* @version v1.0
* @author w
* @date 2019年11月3日下午2:16:31
**/
public class StudentComparable extends Student implements Comparable {
@Override
public int compareTo(StudentComparable o) {
/**
* 需求: age 年龄从 小到大 排列, score 分数从 大 到 小 排列
*/
if(this.getAge()-o.getAge() ==0) {
// 年龄相同,判断分数 .
//注意分数是大到小排列, 所以是 o.getScore() - this.getScore()。
return (int) (o.getScore() - this.getScore());
}else {
return this.getAge()-o.getAge();
}
}
public StudentComparable() {
super();
}
public StudentComparable(String name, int age, double score) {
super(name, age, score);
}
}
4、定义 StudentComparableTest 类,测试排序功能
/**
* description: 测试 Compareable 排序
* @version v1.0
* @author w
* @date 2019年11月3日下午2:16:31
**/
public class StudentComparableTest {
@Test
public void test() {
StudentComparable s1 = new StudentComparable("小明", 18, 60D);
StudentComparable s2 = new StudentComparable("小红", 15, 90D);
StudentComparable s3 = new StudentComparable("小刚", 22, 80D);
StudentComparable s4 = new StudentComparable("小刚", 22, 85D);
List list = new ArrayList();
list.add(s1);
list.add(s2);
list.add(s3);
list.add(s4);
// 排序前
System.out.println(list);
Collections.sort(list);
// 排序后
System.out.println(list);
}
}
5、结果如下:
[Student [name=小明, age=18, score=60.0], Student [name=小红, age=15, score=90.0], Student [name=小刚, age=22, score=80.0], Student [name=小刚, age=22, score=85.0]]
[Student [name=小红, age=15, score=90.0], Student [name=小明, age=18, score=60.0], Student [name=小刚, age=22, score=85.0], Student [name=小刚, age=22, score=80.0]]
6、根据排序前后的结果,可以看到 年龄是从小到大正序排序的,分数是从大到小倒序排序,达到预期结果。
三、Comparator 接口排序
1、Comparator接口位于java.util.Comparator
2、定义StudentComparator类 继承Student类,实现 Comparator接口,重写compare方法。
/**
* description: 定义StudentComparator类 继承Student类,实现 Comparator接口,重写compare方法
* @version v1.0
* @author w
* @date 2019年11月3日下午5:12:42
**/
public class StudentComparator extends Student implements Comparator {
@Override
public int compare(StudentComparator o1, StudentComparator o2) {
/**
* age 年龄,正序 小到大 , score 分数倒序 大到小。
*/
if(o1.getAge()==o2.getAge()) {
// 注意:分数是 倒序 大到小,所以是 o2-o1.
return (int) (o2.getScore() - o1.getScore()) ;
}else {
return o1.getAge() - o2.getAge();
}
}
public StudentComparator() {
super();
}
public StudentComparator(String name, int age, double score) {
super(name, age, score);
}
}
3、定义 StudentComparatorTest 类,测试排序功能
/**
* description: 测试Comparator
* @version v1.0
* @author w
* @date 2019年11月3日下午9:29:43
**/
public class StudentComparatorTest {
@Test
public void test() {
StudentComparator s1 = new StudentComparator("小明", 18, 60D);
StudentComparator s2 = new StudentComparator("小红", 15, 90D);
StudentComparator s3 = new StudentComparator("小刚", 22, 80D);
StudentComparator s4 = new StudentComparator("小刚", 22, 85D);
List list = new ArrayList();
list.add(s1);
list.add(s2);
list.add(s3);
list.add(s4);
// 排序前
System.out.println(list);
Collections.sort(list,new StudentComparator());
// 排序后
System.out.println(list);
}
}
4、结果如下:
[Student [name=小明, age=18, score=60.0], Student [name=小红, age=15, score=90.0], Student [name=小刚, age=22, score=80.0], Student [name=小刚, age=22, score=85.0]]
[Student [name=小红, age=15, score=90.0], Student [name=小明, age=18, score=60.0], Student [name=小刚, age=22, score=85.0], Student [name=小刚, age=22, score=80.0]]
5、根据排序前后的结果,可以看到 年龄是从小到大正序排序的,分数是从大到小倒序排序,达到预期结果。
6、增加一个测试:按照分数大到小的排序 (结果略)
/**
* description: 按照分数大到小的排序
* @return void
* @version v1.0
* @author w
* @date 2019年11月3日 下午9:34:03
*/
@Test
public void testScore() {
StudentComparator s1 = new StudentComparator("小明", 18, 60D);
StudentComparator s2 = new StudentComparator("小红", 15, 90D);
StudentComparator s3 = new StudentComparator("小刚", 22, 80D);
StudentComparator s4 = new StudentComparator("小刚", 22, 85D);
List list = new ArrayList();
list.add(s1);
list.add(s2);
list.add(s3);
list.add(s4);
// 排序前
System.out.println(list);
Collections.sort(list, new Comparator() {
@Override
public int compare(StudentComparator o1, StudentComparator o2) {
return (int) (o2.getScore() - o1.getScore());
}
});
// 排序后
System.out.println(list);
}
四、总结
1、Comparable 位于 java.lang 包, Comparator 位于 java.util 包。
2、实现Comparable接口需要重写compareTo方法,实现Comparator方法需要重写compare方法, 这两个方法返回值都是int类型。
3、 int result = s1.compareTo(s2); result = 0 , 则 s1=s2 ; result < 0, 则 s1
4、int result = compare(T o1, T o2); 结果同上。 (若是 o2-o1,则反之。)
5、Comparable 接口,java中大部分类已经实现了Comparable(String,BigDecimal,java.util.Date等),用于比较两个对象大小,十分方便。 称之为 自然排序。
6、Comparator 接口,主要用集合中排序(TreeSet ,TreeMap , Collections.sort()),不同需求的排序方式,直接接口实现,易于功能扩展,不影响原代码。 称之为 比较器排序。
BigDecimal 比较大小