Comparable和Comparator有啥不一样

1.Comparable和Comparator对比

Comparable是排序接口,若一个类实现了Comparable接口,就意味着“该类支持排序”,这时调用该类的排序方法时就可以实现排序。

Comparable位于java.lang包下。具体定义如下:

public interface Comparable<T> {
	/**
	** 返回值:
	**	0 =>  this对象与对象o相等
	** 大于0 => this对象大于对象o
	** 小于0 => this对象小于对象o
	**/
    public int compareTo(T o);
}

Comparator 是一个专用的比较器,在集合外部实现排序,当这个对象不支持自比较或者自比较函数不能满足要求时就可以写一个比较器来完成两个对象之间大小的比较。

Comparator位于java.util包下。具体定义如下:

public interface Comparator<T> {
	/**
	** 返回值:
	**   0 => o1 = o2
	**  大于0 => o1 > o2
	**  小于0 => o1 < o2
	**/
	int compare(T o1, T o2);
}

Comparable相当于“内部比较器”,而Comparator相当于“外部比较器”。

2. Comparable和Comparator排序案例

场景一:假设每个学生有4个属性:id,姓名,年龄,成绩。现在需要根据id来进行排序,先使用Comparable实现。

Student.java

public class Student implements Comparable<Student> {

    private String id;
    private String name;
    private int age;
    private Double score;

    public Student(String id, String name) {
        this(id,name,0,0);
    }

    public Student(String id, String name, int age, double score){
        this.id = id;
        this.name = name;
        this.age = age;
        this.score = score;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

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

    public Double getScore() {
        return score;
    }

    public void setScore(Double score) {
        this.score = score;
    }

    /**
     * 根据id排序
     * @param o
     * @return
     */
    @Override
    public int compareTo(Student o) {
        return this.id.compareTo(o.id);
    }

    @Override
    public String toString() {
        String info = new String();
        info = id + '\t' + name + '\t' + age + '\t' + score + '\n';
        return info;
    }
}

StudentComparableTest.java

public class StudentComparableTest {
	public static void main(String[] args) {
		List<Student> list = new ArrayList<Student>();
		list.add(new Student("00001", "a", 20, 90 ));
		list.add(new Student("00007", "b", 19, 95 ));
		list.add(new Student("00004", "c", 21, 94 ));
		list.add(new Student("00003", "d", 20, 92 ));
		
		Collections.sort(list);
		System.out.println("Comparable按序号排序后:");
		System.out.println("学号" + "\t姓名" + "\t年龄" + "\t成绩");
		for (Student student : list) {
			System.out.print(student);
		}
	}
}

运行结果:

Comparable按序号排序后:
学号	姓名	年龄	成绩
00001	a	20	90.0
00003	d	20	92.0
00004	c	21	94.0
00007	b	19	95.0

场景二:现需要按照姓名和成绩两个维度对学生进行排名,如果还是实现Comparable则需要重写Student类,那么有没有办法不重写呢,答案当然是有的,这就是Comparator。

StudentComparatorTest.java

public class StudentComparatorTest {
	public static void main(String[] args) {
	
		List<Student> students = new ArrayList<Student>();
		students.add(new Student("00001", "a", 20, 98 ));
		students.add(new Student("00007", "b", 19, 95 ));
		students.add(new Student("00004", "c", 21, 94 ));
		students.add(new Student("00003", "d", 20, 92 ));

		// 按姓名升序排序
		Collections.sort(students, new ComparatorWithNameUP());
		// 显示学生信息
		System.out.println("按姓名升序排序结果:");
		System.out.println("学号" + "\t姓名" + "\t年龄" + "\t成绩");
		for (int i = 0; i < students.size(); i++) {
			System.out.print(students.get(i));
		}

		// 按姓名降序排序
		Collections.sort(students, new ComparatorWithNameDown());
		// 显示学生信息
		System.out.println("按姓名降序排序结果:");
		System.out.println("学号" + "\t姓名" + "\t年龄" + "\t成绩");
		for (int i = 0; i < students.size(); i++) {
			System.out.print(students.get(i));
		}

		// 按成绩降序排序
		Collections.sort(students, new ComparatorWithScoreDown());
		// 显示学生信息
		System.out.println("按成绩降序排序结果:");
		System.out.println("学号" + "\t姓名" + "\t年龄" + "\t成绩");
		for (int i = 0; i < students.size(); i++) {
			System.out.print(students.get(i));
		}

		// 按成绩升序排序
		Collections.sort(students, new ComparatorWithScoreUp());
		// 显示学生信息
		System.out.println("按成绩升序排序结果:");
		System.out.println("学号" + "\t姓名" + "\t年龄" + "\t成绩");
		for (int i = 0; i < students.size(); i++) {
			System.out.print(students.get(i));
		}
	}
}

// 按姓名进行升序排序的外部类,用Comparator接口
class ComparatorWithNameUP implements Comparator<Student> {

	@Override
	public int compare(Student arg0, Student arg1) {
		return arg0.getName().compareTo(arg1.getName());
	}
}

// 按姓名进行降序排序的外部类,用Comparator接口
class ComparatorWithNameDown implements Comparator<Student> {

	@Override
	public int compare(Student arg0, Student arg1) {
		return arg1.getName().compareTo(arg0.getName());
	}
}

// 按成绩降序
class ComparatorWithScoreDown implements Comparator<Student> {

	@Override
	public int compare(Student arg0, Student arg1) {
		if (arg1.getScore() > arg0.getScore())
			return 1;
		else {
			if (arg1.getScore() == arg0.getScore())
				return 0;
			else
				return -1;
		}
	}

}

// 按成绩升序
class ComparatorWithScoreUp implements Comparator<Student> {

	@Override
	public int compare(Student arg0, Student arg1) {
		if (arg0.getScore() > arg1.getScore())
			return 1;
		else {
			if (arg0.getScore() == arg1.getScore())
				return 0;
			else
				return -1;
		}
	}
}

运行结果:

按姓名升序排序结果:
学号	姓名	年龄	成绩
00001	a	20	98.0
00007	b	19	95.0
00004	c	21	94.0
00003	d	20	92.0
按姓名降序排序结果:
学号	姓名	年龄	成绩
00003	d	20	92.0
00004	c	21	94.0
00007	b	19	95.0
00001	a	20	98.0
按成绩降序排序结果:
学号	姓名	年龄	成绩
00001	a	20	98.0
00007	b	19	95.0
00004	c	21	94.0
00003	d	20	92.0
按成绩升序排序结果:
学号	姓名	年龄	成绩
00003	d	20	92.0
00004	c	21	94.0
00007	b	19	95.0
00001	a	20	98.0

猜你喜欢

转载自blog.csdn.net/cl2010abc/article/details/105506073