1.背景:
在操作集合的过程中,有时候需要对集合中的元素进行排序,现在就我所了解到的Compareble和Comparator两种方法进行分析,理解其原理,按场景选择合适的比较方法。
2.Compareble介绍
Compareble是一个排序接口。如果一个类实现了该接口,就说明该类支持排序。即说明可以通过Collections.sort()或 Arrays.sort()方法进行排序。此外,实现Comparable 接口的类的对象 可以用作 “有序映射 ( 如 TreeMap)” 中的键或 “有序集合 (TreeSet)” 中的元素,而不需要指定比较器。
该接口的定义如下:
public interface Comparable<T> {
public int compareTo(T o);
}
我们会通过例如a.compareTo(b)这样的代码来比较两个类的大小,如果返回的int类型为负数,意味着a<b,返回为0的话,意味着a=b,返回为正数,意味着a>b。
举个例子:
覆写compareTo : 设计一个有序Person类,实现了Comparable接口, 以年龄为第一关键字,姓名为第二关键字升序排序。
package java.lang;
import java.util.*;
public int compareTo(Person person) {
int cop = age - person.getAge();
if (cop != 0)
return cop;
else
return name .compareTo(person. name );
}
3.Comparator 介绍
如果类的设计在开始时没有考虑到Compare的问题,可以通过外部的Comparator来进行实现。Comparator可以根据自己的需求来设计想要的排序方式,比如说根据id升序排序,或者说根据id降序排序等。
该接口的定义如下:
package java.util.*;
public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);
}
如果一个类要实现Comparator接口:他一定要复写compare()方法,但是可以不实现equals()方法。因为在根类Object类中已经有了默认的该方法。同样的 int compare(a,b)是比较a和b的大小,返回负数意味着 a<b,返回0意味着a=b,返回正数意味着a>b。
举个例子:Student想根据age进行排序
Student stu[] = {
new Student("张三" ,23),
new Student("李四" ,26),
new Student("王五" ,22)};
Arrays.sort(stu,new MyComparator());
List<Student> list = new ArrayList<Student>();
list.add( new Student("zhangsan" ,31));
list.add( new Student("lisi" ,30));
list.add( new Student("wangwu" ,35));
Collections.sort(list,new MyComparator());
/**
* @desc MyComparator比较器
* 它是“Student的age的升序比较器”
*/
private static class MyComparator implements Comparator<Person> {
@Override
public int compare(Student p1, Student p2) {
return p1.getAge() - p2.getAge();
}
}
4.两者的比较
其实我们可以发现,实现了Comparable这个排序接口,就意味着该集合内部是支持排序的,而Comparator这个接口像是一种比较器的存在,我们如果需要更新下某个类的排序次序,则可以建立一个相对应的比较器。
总的说来前者比较固定、内部,后者比较灵活、外部。
5.参考文献
https://segmentfault.com/a/1190000002514187
http://www.cnblogs.com/skywang12345/p/3324788.html