java比较器Comparable和Comparator的异同

一. 概述
       比较器Comparable 和 Comparator 都可以用来实现集合中元素的比较、排序。 Comparator位于包java.util下,而Comparable位于包java.lang下。Comparable接口将 比较代码嵌入自身类中,而Comparator在一个独立的类中实现比较。
众所周知,诸如Integer、String等这些基本类型的JAVA封装类都已经实现了 Comparable接口,这些类对象本身就支持自比较,可以通过 Collections.sort(和 Arrays.sort)就可以对元素进行排序,无需自己去实现Comparable接 口。对于大多数自定义的类的List序列,当这个对象不支持自比较或者自比较函数不能满 足需求时,我们可以写一个比较器来完成两个对象自己大小的比较,也就是指定使用 Comparator。如果不指定Comparator那么就需要使用自然规则排序,这里的自然顺序 就是实现Comparable接口设定的排序方式。

二. 代码示例
       查看API可知,Comparable接口对实现它的每个类的对象强加一个整体排序。这个 排序被称为类的自然排序 ,类的compareTo方法被称为其自然比较方法。如果开发者 add进入一个Collection的对象想要Collections的sort方法帮你自动进行排序的话,那么 这个对象必须实现Comparable接口。Comparable也被称作内比较器,它的实现比较依 赖于compareTo方法。
compareTo方法的返回值是int,有三种情况: a) 比较者大于被比较者(也就是compareTo方法里面的对象),那么返回正整数 b) 比较者等于被比较者,那么返回0 c) 比较者小于被比较者,那么返回负整数

[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
// Comparable 比较示例
// 定义一个Student类,实现Comparable接口并重写compareTo方法
public class Student implements Comparable<Student> {
    private String id;
    private String username;
    private Integer age;
    // 省略了  set and get
    public int compareTo(Student o) {
        if (this.age > o.getAge()) {
            return 1;
        } else if (this.age < o.getAge()) {
            return -1;
        } else {
            return 0;
        }
    }
}
[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
// 测试类 (测试Comparable比较器)
public class Test1 {
    public static void main(String[] args) {
 
        Student[] stu = new Student[3];
        stu[0] = new Student("1", "zhangsan", 11);
        stu[1] = new Student("2", "lisi", 15);
        stu[2] = new Student("3", "wangwu", 13);
        Arrays.sort(stu);
 
        for (int i = 0; i < stu.length; i++) {
            System.out.println(stu[i].getId() + " "
                               + stu[i].getUsername()
                               + " " + stu[i].getAge());
        }
    }
}


        查看API可知,Comparable强行对某个对象 collection 进行整体排序的比较函数。 可以将比较器Comparator 传递给 sort 方法(如 Collections.sort 或 Arrays.sort),从而允 许在排序顺序上实现精确控制。还可以使用 Comparator 来控制某些数据结构(如有 序 set或有序映射)的顺序,或者为那些没有自然顺序的对象 collection 提供排序。
Comparator接口里面有一个compare方法,方法有两个参数T o1和T o2,是泛型的表示 方式,分别表示待比较的两个对象,方法返回值和Comparable接口一样是int,有三种 情况: a)  o1大于o2,返回正整数 b)  o1等于o2,返回0 c)  o1小于o3,返回负整数

[Java] 纯文本查看 复制代码
?
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// Comparator 比较示例
public class Test2 {
    public static void main(String[] args) {
 
        List<Student> stus = new ArrayList<>();
        stus.add(new Student("1", "zhengsan", 11));
        stus.add(new Student("2", "lisi", 15));
        stus.add(new Student("3", "wangwu", 13));
 
        Collections.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;
                }
            }
        });
 
        stus.forEach((Student stu) -> {
            System.out.println(stu.getId() + " " + stu.getUsername() + " " + stu.getAge());
        });
    }
}


三. 差异比较
Comparable和Comparator的区别

 

参数 Comparable     Comparator
接口所在包 java.lang.Comparable java.util.Comparator
排序逻辑 必须在待排序对象的类内部实现 排序逻辑在外部实现
实现方式 待排序对象的类内部实现Comparable 接口 调用时实现Comparator接 口
排序方法 int compareTo(T o) int compare(T o1, T o2)

四. 优缺点:
优点:
1.Comparable被称为自然排序,如果使用者恰好需要数据遵循自然排序,完全不需要做 任何实现,直接调用Arrays.sort()就可以完成排序。
2.Comparator被称为外部排序,如果实现类没有实现Comparable接口或实现类里面的 排序不能满足要求,则可以实现Comparator去自定义比较器来写自己的算法。
缺点:
1.Comparable在实现类中必须实现其接口,耦合性比较高。如果算法要进行修改,实现 类必须进行修改维护起来也比较麻烦。
2.如果实现类没有实现任何排序,想要对自定义对象进行排序,Comparator必须自定义 比较器并写比较算法。 五. 总结
1.如果自定义的类需要对数据排序,最好根据需求来取舍是使用那一种或两种综合使用。
2.一般需要做比较的逻辑都可以使用的上Comparator,最常用的场景就是排序,排序常 使用Arrays和Collections的sort方法。排序时,两个对象比较的结果有三种:大于,等 于,小于。
3.如果实现类没有实现Comparable接口,又想对两个类对象进行比较(或者实现类实现了 Comparable接口,但是对compareTo方法内的比较算法不满意),那么可以实现 Comparator接口并自定义一个比较器,写比较算法。
4.实现Comparable接口的方式比实现Comparator接口的耦合性要强一些,如果要修改 比较算法就需要修改Comparable接口的实现类。如果说我们将实现类的.class文件打成 一个.jar文件提供给开发者使用的时候,每次改动就必须提供给使用者最新的.jar包,维 护起来很麻烦。实现Comparator的类是在外部进行比较的,不需要对实现类有任何修 改,使用起来就非常方便。

发布了923 篇原创文章 · 获赞 11 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/xiaoyaGrace/article/details/105135034
今日推荐