Java接口Comparable和Comparator的区别

先看下面一段代码:

        List<String> list=new ArrayList<>();        list.add("x");        list.add("a");        list.add("c");        list.add("y");
        Collections.sort(list);        System.out.println(list);

输出结果:

[a, c, x, y]

这是一段非常简单的使用集合工具类排序的代码,这里有个问题,我们什么也没指定,默认就按字母升序排了,这是为什么?通过查看String类的源码,我们能够发现其实现了三个接口,如下:

class String implements java.io.Serializable, Comparable<String>, CharSequence

注意其中的第二个接口Comparable,实现了该接口的类,相当于默认定义了该类在集合里面的自然排序的方式。

Java里面关于对象排序一般离不开两个接口:Comparable和Comparator,那么它们两者有什么区别呢?

Comparable:提供自然排序的定义,比如String类提供了字母序,Integer类提供了大小序,等在Java中基本类型的包装类都提供了自然排序的默认的实现,这也是我们为什么能直接使用Collections.sort函数来获取一个排序的结果,那是因为这些类都必须实现了Comparable接口才可以,如果你自定义一个类,没有实现该接口,直接尝试调用这个方法会直接编译错误。

Comparator:非自然排序的接口,可以不需要改动原类,从外部自定义一个排序规则来实现排序。比如上面的String类,我们默认调用Collections.sort来对集合进行按字符串升序,但如果我们想要一个降序的结果集应该怎么办?有的同学可能已经想到了使用集合的Collections.reverse()方法就可以,这样确实可以,更优雅的办法我们的可以使用Comparator接口,来定义一个外部排序规则,如下:

   class StringComparator implements Comparator<String>{
       @Override       public int compare(String o1, String o2) {           return -o1.compareTo(o2);       }   }

然后调用集合工具类的第二种的排序方法:

 Collections.sort(list, new StringComparator());

输出结果如下:

[y, x, c, a]

当然如果用了Java8,上面可以不用新定义一个排序规则类,可以直接使用lambda函数使得代码更简洁。

什么时候应该用Comparable或者Comparator?

如果你想给你自定义的类提供默认的自然顺序,那么Comparable是一个好的选择。如果对类里面自带的自然排序不满意,而又不能修改其源代码的情况下,使用Comparator就比较合适。此外使用Comparator可以避免添加额外的代码与我们的目标类耦合,同时可以定义多种排序规则,这一点是Comparable接口没法做到的,从灵活性和扩展性讲Comparator更优,故在面对自定义排序的需求时,可以优先考虑使用Comparator接口。

原文发布于微信公众号 - 我是攻城师(woshigcs)

原文发表时间:2019-03-31

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券