Comparable 与 Comparator 的区别

1、Comparable  

Comparable 可以认为是一个内比较器,实现了Comparable 接口的类有一个特点,就是这些类可以和自己比较,至于具体和另外一个实现了Comparable 接口的类如何比较,则需要依赖compareTo方法的实现,compareTo方法也被称为自然比较方法,如果开发者add进入一个Collection的对象想要用Colllections.sort()方法,进行排序的话,那么这个对象必须实现Comparable 接口。

package action;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class Student implements Comparable<Student>{

	private int age;
	private String name;
	
	
	public Student(int age) {
		super();
		this.age = age;
	}

	public Student(int age, String name) {
		super();
		this.age = age;
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public int compareTo(Student o) {
		
		if(this.age - o.getAge() > 0){
			return 1;
		}else if (this.age - o.getAge() < 0) {
			return -1;
		}else {
			return 0;
		}
		
	}
	
	@Override
	public String toString() {
		return "Student [age=" + age + "]";
	}

	public static void main(String[] args) {
		List<Student> list = new ArrayList<>();
		list.add(new Student(8));
		list.add(new Student(9));
		list.add(new Student(11));
		list.add(new Student(10));
		System.out.println(list);
		
		Collections.sort(list);
		Student s1 = new Student(5);
		Student s2 = new Student(9);
		System.out.println(s1.compareTo(s2));
		
		System.out.println(list);
	}
}

 Comparable 与 Comparator 的区别

 最终是使用二分查找的对数组[]进行排序,

注意一下,前面说实现Comparable接口的类是可以支持和自己比较的,但是其实代码里面Comparable<T>泛型未必一定是实现此接口的类(如:Student),也可以是String或者其他类型都可以,只要开发者指定可具体的比较算法就可以。

2、Comparator

Comparator 可以认为是一个外比较器,个人认为有两种情况可以使用Comparator接口;

  1. 一个对象不支持自己可自己比较(没有实现Comparable接口),但是又想对两个对象进行比较;
  2. 一个对象实现了Comparable接口,但是开发着认为compareTo方法中的比较方式并不是自己想要的那种表达方式;

Comparator 接口里面有一个compare方法,方法中有两个参数T o1 和 T o2,是泛型的表示方式,分别表示待比较的两个对象,方法返回值和 Comparable接口一样是 int 。

package actionPerform;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class Student {

	private int age;
	private String name;

	public Student(int age) {
		super();
		this.age = age;
	}

	public Student(int age, String name) {
		super();
		this.age = age;
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "Student [age=" + age + "]";
	}

	public static void main(String[] args) {
		List<Student> list = new ArrayList<>();
		list.add(new Student(8));
		list.add(new Student(9));
		list.add(new Student(11));
		list.add(new Student(10));
		System.out.println(list);

		Collections.sort(list, new Comparator<Student>() {

			@Override
			public int compare(Student o1, Student o2) {
				if (o1.getAge() - o2.getAge() > 0) {
					return 1;
				} else if (o1.getAge() - o2.getAge() < 0) {
					return -1;
				} else {
					return 0;
				}
			}
		});

		System.out.println(list);
	}
}

Comparable 与 Comparator 的区别 

当然因为泛型指定死了,所以实现Comparator 接口的实现类只能是两个相同的对象;

3、总结

两种比较器 Comparator 和 Comparable ,相比有点如下:

  • 如果实现类没有实现 Comparable 接口,又想对两个类进行比较(或者实现类实现Comparable 接口,但是对compareTo方法内的比较算法不满意),那么可以实现Comparator 接口,自定义一个比较器,写比较算法;
  • 实现 Comparable 接口的方式比实现 Comparator 接口的耦合性要强一些,如果要修改比较算法,要修改Comparable的实现类,而实现 Comparator 的类是在外部进行比较的,不需要对实现类进行修改。从这个角度上说,尤其是我们将实现类的 .class 文件打成一个 .jar 文件提供给开发者使用时。实际上实现Comparator 接口的方式,就是一种典型的策略模式。