jdk1.8.0_144

一知半解写代码, 集合排序用个啥。 抄起键盘胡乱打, 似懂非懂最可怕。

  Comparable与Comparator都是用于集合的排序,对于大多数人来说Comparator可能略微比Comparable要熟悉一点,类似下面这几句代码的使用频率应该是最高的。

Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o1.compareTo(o2);
}
});

  这是一段对集合排序的代码。

  对于集合排序时比较器的使用往往止步于此,以至于更为深层次的使用似懂非懂,更为复杂的排序不知所措。

  Comparable用于集合内部定义的方法实现的排序,Comparator用于集合外部实现的排序。

  我们从Collections.sort的两个重载方法开始

public static <T extends Comparable<? super T>> void sort(List<T> list)

public static <T> void sort(List<T> list, Comparator<? super T> c)

  这两个方法都是泛型方法,第一个方法只传递一个List参数进行排序,第二个方法传递一个List参数加上一个Comparator比较器。

public static <T extends Comparable<? super T>> void sort(List<T> list)

  Collections.sort方法用于对List集合进行排序,思考一个问题,这个只有一个参数的List如何进行排序呢?它是按照怎样的规则进行排序呢?答案就在这个泛型方法的泛型类型之中“<T extends Comparable<? super T>>”,List集合中的元素需要实现Comparable接口,Comparable接口也是一个泛型,并要求它的泛型类型需要是集合中的元素的超类(或自身)。重点在于——集合中的元素需要是实现Comparable接口。也就是说在使用Collections.sort(List)这个方法对集合中的元素进行排序时,需要集合中的元素实现了Comparable接口,这才能进行排序。

 

public static <T> void sort(List<T> list, Comparator<? super T> c)

  这个方法同样是一个泛型方法,与上面的方法不同的是对集合中的元素类型并没有做限制,要对这个集合进行排序需要指定一个Comparator比较器,这个比较器的泛型类型需要是集合元素的超类(或自身)。

  通过上面这两个方法比较容易的能得出一个浅显的结论,Comparable和Comparator都是用于比较、排序,如果元素自身已经实现了Comparable接口,则可以利用它自身进行比较排序,如果元素自身没有实现Comparable接口,则可以利用外部实现Comparator比较器对元素进行比较排序。这也就是前面提到的Comparable用于集合内部定义的方法实现的排序,Comparator用于集合外部实现的排序。 接着来看Comparable接口和Comparator接口。

  接着来看Comparable接口和Comparator接口。

Comparable

public int compareTo(T o)

  这个接口只定义了一个compareTo方法,在很多“值类型”的数据类型,例如String、Integer、Long等已经实现了这个接口。

  对于这个方法和equals方法有类似的地方,equals强调的更多是相等于否,而compareTo强调更多的比较,如果x < y,则返回-1;x = y,则返回0;x > y,则返回1。实现这个方法时同样需要遵循几个规则:

  1. 自反性,如果x <y ,那么x.compareTo(y)返回-1,同理y.compareTo则返回1;
  2. 传递性,如果x.compareTo(y)返回-1,y.compareTo(z)返回-1,则x.compareTo(z)也应该返回-1;
  3. 同一性,如果x.compareTo(y)返回0(x = y),那么若x.compareTo(z)返回-1时,y.compareTo(z)也应该返回-1。

  有兴趣的可以查看String类中对于compareTo方法的实现,它的排序规则是将字符串转换为字符数组逐个按照字典序排序。

Comparator

int compare(T o1, T o2)

boolean equals(Object obj)

  这个接口在JDK8中对它进行了较大的改进,在JDK8之前只包含上面两个方法,而JDK8则达到了18个方法,其中都是接口的default方法,和static静态方法,所以并不需要在实现时额外实现。

  在JDK8中该类添加了@FunctionalInterface函数式接口的注解,函数式接口表明在接口中只含有一个方法作为Lambda表达式的数据类型,在《JDK8的新特性——Lambda表达式》中有提到,Java中定义如果覆盖了Object中的方法则不算,所以在Comparator接口中只有一个compare方法。对于@FunctionalInteface注解可加不可加,加上只是为了让编译器做更好的检查,要求只能定义一个方法,不加编译器便不对此进行检查。

  compare方法和compareTo方法类似,它同样需要满足上面提到的:自反性、传递性、同一性。并且它强调,不必严格满足“(compare(x, y)==0) == (x.equals(y))”,当然最好说明白。

  对于这个类,更多的是需要理解学习它所运用的设计模式——策略模式。策略模式,不改变对象自身,而是用另一个对象来改变它的行为。例如,超市减价操作,有10件商品需要统一降价1半进行处理,我们可以在这10件商品的价格上全部做修改减少至它的一半,10件好处理,如果N件呢,甚至我们还需要对其进行降价呢?此时我们则可以使用一种“策略”——商品全部打5折。这就是利用另外一个对象来改变一个对象的行为,而不是简单粗暴地修改原有对象。说回此处,如果List中的元素本身没有实现Comparable接口,但我们需要对它进行排序,我们可以对原有对象进行修改让它实现Comparable接口,但凡涉及修改代码都不优美,此时我们则可以利用策略模式,也就是实现一个Comparator接口对集合中的元素进行排序。

这是一个能给程序员加buff的公众号 

似懂非懂的Comparable与Comparator的更多相关文章

  1. Java中Comparable与Comparator的区别

    相同 Comparable和Comparator都是用来实现对象的比较.排序 要想对象比较.排序,都需要实现Comparable或Comparator接口 Comparable和Comparator都 ...

  2. 对象比较器:Comparable和Comparator

    在进行对象数组排序的过程中需要使用到比较器,比较器有两个:Comparable和Comparator ①.java.lang.Comparable:是在类定义是时候默认实现好的接口,里面提供有一个co ...

  3. Java中Comparable和Comparator接口区别分析

    Java中Comparable和Comparator接口区别分析 来源:码农网 | 时间:2015-03-16 10:25:20 | 阅读数:8902 [导读] 本文要来详细分析一下Java中Comp ...

  4. Comparable和Comparator的区别

    Comparable Comparable可以认为是一个内比较器,实现了Comparable接口的类有一个特点,就是这些类是可以和自己比较的,至于具体和另一个实现了Comparable接口的类如何比较 ...

  5. Java中Comparable和Comparator区别小结

    一.Comparable简介 Comparable是排序接口.若一个类实现了Comparable接口,就意味着该类支持排序.实现了Comparable接口的类的对象的列表或数组可以通过Collecti ...

  6. Java 中 Comparable 和 Comparator 比较

    Java 中 Comparable 和 Comparator 比较 目录: Comparable Comparator Comparable 和 Comparator比较 第二个例子 之 Compar ...

  7. Comparable与Comparator

    转载 Comparable与Comparator的区别 (转载) Comparable & Comparator 都是用来实现集合中元素的比较.排序的,只是 Comparable 是在集合内部 ...

  8. Java中的TreeMap、Comparable、Comparator

    我们知道HashMap的存储位置是按照key这个对象的hashCode来存放的,而TreeMap则是不是按照hashCode来存放,他是按照实现的Comparable接口的compareTo这个方法来 ...

  9. 比较器comparable与comparator的使用

    在Java学习和使用里,工具类与算法类(collections和Arrays)也是我们使用比较多的,在它们里面就包含了comparable与comparator这两种比较器. 一.比较器的分类与概念 ...

随机推荐

  1. 程序员之殇 —— (The Beginning of the End)噩梦、崩坏

    Look at all those faces out there (当我环视周遭的一张张脸孔) We are so different(我们是如此的不同) But we have one thing ...

  2. Java Web学习路线图

    三张Java Web完整学习路线图,阶段一和JavaSE部分可不学

  3. Core Graphics框架是Quartz的核心,也是内容描画的基本接口。

    Core Graphics框架是Quartz的核心,也是内容描画的基本接口.

  4. mysql索引使用注意事项

    索引是快速搜索的关键.MySQL索引的建立对于MySQL的高效运行是很重要的.下面介绍几种常见的MySQL索引类型. 在数据库表中,对字段建立索引可以大大提高查询速度.假如我们创建了一个 mytabl ...

  5. eclipse导入web项目变成java项目解决办法

    右键工程,properties-> Project Facets-> 点convert to faceted..连接 -> 把Dynamic Web Moudle勾上

  6. .net 和 core2.0 数据库连接字符串

    Asp.net Core 数据库离线文件的连接(引自“张不水”兄的研究成果.) 一.绝对路径: "DefaultConnection": "Data Source=(lo ...

  7. 2017-07-10(lastlog rpm yum)

    lastlog 查看所有用户最后一次登录的时间 rpm www.rpmfind.net   用来确认函数库需要安装哪个依赖程序的的网站 rpm -ivh  包全名 (安装) rpm -Uvh 包全名( ...

  8. Django_xamdin安装与使用

    有比Django更加强大的admin? xadmin? pip install xadmin 如何让xadmin生效? 新增两个注册app,xadmin,crispy_forms,通过run mana ...

  9. python_5_模块

    创:5_4_2017 修: 什么是模块? --标准库+第三方库+自定义,为实现某一方面的功能集合(变量,函数,类) 如何安装第三方库? --pip install 第三方库 如何导入和使用模块? -- ...

  10. 三十天学不会TCP,UDP/IP网络编程 - UDP的实践--DHCP

    在经历了一顿忙碌加出去玩了玩之后,我又开始重新更新了~这是最新的一篇~完整版可以去gitbook(https://www.gitbook.com/@rogerzhu/)看到,在gitbook的后台流量 ...