Java比较器-Comparable和Comparator

比较器的作用

在Java中经常会涉及到对象数组的排序问题,那么就涉及到对象之间的比较问题。
通常对象之间的比较可以从两个方面去看:
第一个方面:对象的地址是否一样,也就是是否引用自同一个对象。这种方式可以直接使用“==“来完成。
第二个方面:以对象的某一个属性的角度去比较。
在JDK8中,有三种实现对象比较的方法:

  1. 覆写Object类的equals(()方法;
  2. 继承Comparable接口,并实现compareTo()方法;
  3. 定义一个单独的对象比较器,继承自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);
	}

}
posted @ 2020-03-17 12:03  我不是忘尘  阅读(272)  评论(0)    收藏  举报