Java比较器-Comparable和Comparator
比较器的作用
在Java中经常会涉及到对象数组的排序问题,那么就涉及到对象之间的比较问题。
通常对象之间的比较可以从两个方面去看:
第一个方面:对象的地址是否一样,也就是是否引用自同一个对象。这种方式可以直接使用“==“来完成。
第二个方面:以对象的某一个属性的角度去比较。
在JDK8中,有三种实现对象比较的方法:
- 覆写Object类的equals(()方法;
- 继承Comparable接口,并实现compareTo()方法;
- 定义一个单独的对象比较器,继承自Comparator接口,实现compare()方法。
本文主要研究后两种方法
Comparable接口
源码:
public interface Comparable<T> {
/*
参数: T o -> 参与比较的元素
返回值: int -> 比较的结果
升序规则:this 和 o
this.属性 > o.属性 正数
== 0
< 负数
*/
public int compareTo(T o);
}
继承Comparable接口,并实现compareTo()方法;
class Student implements Comparable<Student>{
private int no;
private String name;
private int age;
private int score;
public Student(int no, String name, int age,int score) {
super();
this.no = no;
this.name = name;
this.age = age;
this.score = score;
}
public int getNo() {
return no;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public int getScore() {
return score;
}
@Override
public String toString() {
return "Student [no=" + no + ", name=" + name + ", age=" + age + ",score=" + score +"]";
}
@Override
public int compareTo(Student o) {
//--------------------- 学号升序-----------------------
// this.no o.no
/*if(this.no > o.no){
return 1;// 顺序的改变
}else if(this.no == o.no){
return 0;
}else {
return -1;
}*/
return this.no - o.no;
}
@Override
public int compareTo(Student o) {
//--------------------- 分数降序-----------------------
// this.score o.score
/*if(this.score > o.score){
return -1;
}else if(this.score < o.score){
return 1;// 顺序的改变
}else {//
return 0;
}*/
return o.score - this.score;
}
// 名字 String 升序
public int compareTo(Student o) {
//--------------------- 分数降序-----------------------
// this.name o.name
/* if(this.name.compareTo(o.name) > 0){
return 1;// 顺序的改变
}else if(this.name.compareTo(o.name) < 0 ){
return -1;
}else {//
return 0;
}*/
return this.name.compareTo(o.name);
}
}
public class TestSort2 {
public static void main(String[] args) {
Student guojing = new Student(11, "guojing", 20,100);
Student yangkang = new Student(33, "yangkang", 21,90);
Student huangrong = new Student(22, "huangrong", 19,99);
Student [] stus = {guojing,yangkang,huangrong};
/*
*在使用java.util.Arrays.sort()方法时,不用指定具体的比较器,sort()方法会使用对象自己的比较函数来完成对象的排序。
*/
Arrays.sort(stus);
Arrays.stream(stus).forEach(System.out::println);
}
}
Comparator接口
源码:
@FunctionalInterface
public interface Comparator<T> {
/*
参数: o1,o2 -> 用来比较的对象
返回值: int -> 比较的结果
升序比较的规则:
o1.属性 > o2.属性 返回正数
< 负数
== 0
*/
int compare(T o1, T o2);
}
使用Comparator的情形:要在已经开发好的代码的基础上完善对象的比较功能时,又不想更改之前的代码,这种情况下,我们需要单独定义一个对象比较器,继承Comparator接口,并实现compare()方法。
class MyComparator implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
// 年龄升序
// o1.年龄 o2.年龄
if(o1.getAge() > o2.getAge()){
return 1;// 顺序改变
}else if(o1.getAge() < o2.getAge()){
return -1;
}else {
return 0;
}
}
public class TestSort3 {
public static void main(String[] args) {
Student guojing = new Student(11, "guojing", 20, 100);
Student yangkang = new Student(33, "yangkang", 21, 90);
Student huangrong = new Student(22, "huangrong", 19, 99);
Student[] stus = { guojing, yangkang, huangrong };
// 1. 创建一个比较器对象
MyComparator my = new MyComparator();
Arrays.sort(stus, my);
Arrays.stream(stus).forEach(System.out::println);
}
}
除了通过创建一个类实现Comparator接口,也可以通过匿名内部类的方式实现一次性的比较规则:
public class TestSort3 {
public static void main(String[] args) {
Student guojing = new Student(11, "guojing", 20, 100);
Student yangkang = new Student(33, "yangkang", 21, 90);
Student huangrong = new Student(22, "huangrong", 19, 99);
Student[] stus = { guojing, yangkang, huangrong };
// 默认:自然排序。学号升序
Arrays.sort(stus);
// 1. 创建一个比较器对象
MyComparator my = new MyComparator();
Arrays.sort(stus, my);
// 2. 一次性的比较规则
Arrays.sort(stus, new Comparator<Student>(){
@Override
public int compare(Student o1, Student o2) {
// 年龄 升序
if(o1.getAge() > o2.getAge()){
return 1;
}else if(o1.getAge() < o2.getAge()){
return -1;
}else {
return 0;
}
// 简化
return o1.getAge() - o2.getAge();
}
});
// 3. 一次性的规则
Arrays.sort(stus, new Comparator<Student>(){
@Override
public int compare(Student o1, Student o2) {
// 年龄降序
return o2.getAge() - o1.getAge();
}
});
// 4. 一次性的规则:Lambda
Arrays.sort(stus,(stu1,stu2)->stu2.getAge() - stu1.getAge() );
Arrays.stream(stus).forEach(System.out::println);
}
}

浙公网安备 33010602011771号