Comparable与Comparator
来源:互联网 发布:淘宝怎么去除同款 编辑:程序博客网 时间:2024/06/06 01:22
1、Comparable接口:需要一个具体的类实现
一个类实现了 Camparable 接口表明这个类的对象之间是可以相互比较的。如果用数学语言描述的话就是这个类的对象组成的集合中存在一个全序。这样,这个类对象组成的集合就可以使用 Sort 方法排序了。
这个接口定义在java.lang包下,其源代码如下:
- public interface Comparable<T> {
- public int compareTo(T o);
- }
这个接口支持泛型,在实现compareTo()方法时可限定具体的比较类型。下面来举一个例子,如下:
- public class PersonBean implements Comparable<PersonBean> {
- public PersonBean(int age, String name) {
- this.age = age; // 引用类型
- this.name = name; // 基本类型
- }
- int age = 0;
- String 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;
- }
- // 覆写equals和hashCode方法
- public boolean equals(Object o) {
- if (!(o instanceof PersonBean)) {
- return false;
- }
- PersonBean p = (PersonBean) o;
- return (age == p.age) && (name.equals(p.name));
- }
- public int hashCode() {
- int result = 17;
- result = 31 * result + age;
- result = 31 * result + name.hashCode();
- return result;
- }
- public String toString() {
- return (age + "{" + name + "}");
- }
- public int compareTo(PersonBean person) {
- int cop = age - person.getAge();
- if (cop != 0)
- return cop;
- else
- return name.compareTo(person.name);
- }
- }
如果两个人的年龄相同,则通过字符串类中的compareTo()方法进行比较。来看String类的定义如下:
- public final class String implements java.io.Serializable, Comparable<String>, CharSequence
- public int compareTo(String anotherString) {
- int len1 = value.length;
- int len2 = anotherString.value.length;
- int lim = Math.min(len1, len2); // 返回len1和len2中长度较小的一个
- char v1[] = value;
- char v2[] = anotherString.value;
- int k = 0;
- while (k < lim) { // 根据字符序列中所含字符的Unicode编码值来比较
- char c1 = v1[k];
- char c2 = v2[k];
- if (c1 != c2) {
- return c1 - c2;
- }
- k++;
- }
- return len1 - len2; // 如果两个字符串的k个字符相等,则长度较小的在前
- }
字符串最后都是转换为字符数组进行比较的。
- public class testComparabl {
- public void compare() {
- PersonBean[] p = { new PersonBean(20, "Tom"),
- new PersonBean(20, "Jeff"), new PersonBean(30, "Mary"),
- new PersonBean(20, "Ada"), new PersonBean(40, "Walton"),
- new PersonBean(61, "Peter"), new PersonBean(20, "Bush") };
- System.out.println("before sort:\n" + Arrays.toString(p));
- Arrays.sort(p);
- System.out.println("after sort:\n" + Arrays.toString(p));
- }
- public static void main(String[] args) {
- testComparabl tc = new testComparabl();
- tc.compare();
- }
- }
[20{Tom}, 20{Jeff}, 30{Mary}, 20{Ada}, 40{Walton}, 61{Peter}, 20{Bush}]
after sort:
[20{Tom}, 20{Jeff}, 20{Bush}, 20{Ada}, 30{Mary}, 40{Walton}, 61{Peter}]
2、Comparator接口:被用于各个需要比较功能的类使用。
作用有两个:
- 如果类的设计师没有考虑到 Compare 的问题而没有实现 Comparable 接口,可以通过 Comparator 来实现比较算法进行排序;
- 为了使用不同的排序标准做准备,比如:升序、降序或其他什么序。
这个接口定义在com.util包下,源代码如下:
- public interface Comparator<T> {
- int compare(T o1, T o2);
- boolean equals(Object obj);
- }
在这个接口中定义了两个方法。
- class PersonBean{ // 没有实现Comarable接口
- public PersonBean(int age, String name) {
- this.age = age;
- this.name = name;
- }
- int age = 0;
- String 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;
- }
- public String toString() {
- return (age + "{" + name + "}");
- }
- }
可以不用实现equals()方法,因为类默认继承Object对象,Object对象中提供了对equals()方法的实现。
- public class AlphDesc implements Comparator<PersonBean> { // 自定义排序规则
- public int compare(PersonBean personA, PersonBean personB) {
- int cop = personA.age - personB.age;
- if (cop != 0)
- return cop;
- else
- return personB.getName().compareTo(personA.getName());
- }
- }
运行如上程序:
- PersonBean[] p = { new PersonBean(20, "Tom"),
- new PersonBean(20, "Jeff"), new PersonBean(30, "Mary"),
- new PersonBean(20, "Ada"), new PersonBean(40, "Walton"),
- new PersonBean(61, "Peter"), new PersonBean(20, "Bush") };
- System.out.println("before sort:\n" + Arrays.toString(p));
- AlphDesc desc = new AlphDesc();
- Arrays.sort(p, desc);
- System.out.println("after sort:\n" + Arrays.toString(p));
运行结果如下:
before sort:
[20{Tom}, 20{Jeff}, 30{Mary}, 20{Ada}, 40{Walton}, 61{Peter}, 20{Bush}]
after sort:
[20{Tom}, 20{Jeff}, 20{Bush}, 20{Ada}, 30{Mary}, 40{Walton}, 61{Peter}]
3、equals()方法与Comarable、Comparator接口的比较
equals()方法定义在Object类中并且提供了简单的实现。而Java中所有的类都继承了equals()方法,类似于Comarable接口,土生土长的,在编写源代码时就定义成这样了。所以你无法改变Object类中定义的equals()方法、或者是不可变类String的compareTo()方法。
为了能够按照自己的规则进行比较,Object类中的equals()方法没有加final关键字,允许进行覆盖重写,类似于Comparator接口,允许自定义比较规则。但是与Comparable接口和Comparator接口比较起来,显得功能不足,专业水准不够。主要体现在如下几个方面:
(1)接口支持范型,可以传入具体的比较类型,而equals()方法以Object类型做为参数,太泛化,比较时容易出问题。如:
- public class test1 {
- public static void main(String args[]) {
- AA aa = new AA();
- BB bb = new BB();
- aa.equals(bb); // 调用aa中的equals()方法
- bb.equals(aa); // 调用bb中的equals()方法
- }
- }
- class AA {
- }
- class BB {
- }
(2)equals()是方法,更加注重面向对象的思想(继承覆盖),而接口是类型,面向的是业务和功能。所以说接口范围更大,在Comparable接口中甚至定义了equals()方法来满足其比较的功能。
下面来比较一下两个接口:
Comparable 是通用的接口,用户可以实现它来完成自己特定的比较,而 Comparator 可以看成一种算法的实现,在需要容器集合实现比较功能的时候,来指定这个比较器,这可以看成一种设计模式,将算法和数据分离。
如果想要了解Arrays.sort()方法的源代码,请点击:
http://www.cnblogs.com/gw811/archive/2012/10/04/2711746.html
- Comparable与Comparator
- Comparable与Comparator
- Comparable与Comparator
- Comparable与Comparator
- Comparable 与 Comparator
- comparable与Comparator
- Comparable与Comparator
- comparable 与 Comparator
- comparable接口与comparator
- Comparable与Comparator区别
- Comparator与Comparable
- Comparable与Comparator
- Comparable与Comparator
- Comparable 与 Comparator
- Comparable接口与Comparator
- Comparator 与 Comparable
- java Comparator 与Comparable
- Comparable与Comparator浅析
- robotium测试工具使用之——输出log日志
- 显著性论文学习阶段总结(二)
- sizeof和strlen 比较经典
- Vision引擎中导入和导出高度图
- QQ通讯原理浅析
- Comparable与Comparator
- 【IOS动画】UIView放大缩小背景淡入淡出动画效果
- Android自动化测试(UiAutomator)——截图功能
- Java 改变图片大小
- 图像/视觉显著性检测技术发展情况梳理(Saliency Detection、Visual Attention)--计算机视觉专题2
- $("#email\\.info").html("邮箱不能为空");中\\符号
- 关于DDR2的功耗计算
- ACM 学习心得 ——2014年ACM暑假集训有感
- 如何用Java编写一段代码引发内存泄露