前言

好久没写博客了,今天研究了一下jdk的比较器,想着随手写个博客吧。

Comparable

首先介绍一下java.util.Comparable这个接口,该接口只有一个方法:/** @param o the object to be compared.

* @return a negative integer, zero, or a positive integer as this object

* is less than, equal to, or greater than the specified object.

**/

public int compareTo(T o);

再简单的引文注释我也会翻译,这是原则问题。那么这里的意思就是,传入一个参数,进行比较,如果调用者比该参数“大”,那么返回正整数,反之返回负整数,相同则返回0。当然,这个”大”是由你自己去定义的。

在jdk8的源码中,很多类都实现了这个接口,如Date,Long,String,Integer等等。看看Date对这个接口的实现源码吧:/**

* Compares two Dates for ordering.

*

* @param anotherDate the Date to be compared.

* @return the value 0 if the argument Date is equal to

* this Date; a value less than 0 if this Date

* is before the Date argument; and a value greater than

* 0 if this Date is after the Date argument.

* @since 1.2

* @exception NullPointerException if anotherDate is null.

*/

public int compareTo(Date anotherDate) {

long thisTime = getMillisOf(this);

long anotherTime = getMillisOf(anotherDate);

return (thisTime

}

如果this的日期在传入参数的日期之前,那么返回负整数,反之返回正整数,相等返回0。这里是通过比较两个日期时间戳大小去实现的。

所以Comprable它就是一个很简单的比较器规范。

Comparator

这个东西其实主要就是比较器的稍微高级应用。我看了源码并且做了下翻译,提取出了几个关键的方法。@FunctionalInterface

public interface Comparator {

/**

* 比较o1 o2 如果前者较大就返回正整数,反之返回负整数,相等则返回0

*/

int compare(T o1, T o2);

boolean equals(Object obj);

/**

* 返回一个把规则逆转的比较器 例:当前比较器指定的规则是按时间从小到大排序,那么它会返回一个按时间从大到小的比较器

*/

default Comparator reversed() {

return Collections.reverseOrder(this);

}

/**

* 在当前比较器的基础上拼接一个后续比较器。

* 例如:

* Comparator cmp = Comparator.comparingInt(String::length)

* .thenComparing(String.CASE_INSENSITIVE_ORDER);

* 这是一个比较字符串的代码,意思是先比较字符串的长度,如果长度相等,就用String提供的比较器去比较。

*/

default Comparator thenComparing(Comparator super T> other) {

Objects.requireNonNull(other);

return (Comparator & Serializable) (c1, c2) -> {

int res = compare(c1, c2);

return (res != 0) ? res : other.compare(c1, c2);

};

}

//其实上个方法可以转换成以下形式,这样可能稍微接地气些。

default Comparator thenComparing_back(Comparator super T> other) {

Objects.requireNonNull(other);

Comparator comparator = new Comparator() {

@Override

public int compare(T o1, T o2) {

int res = this.compare(o1, o2);

if (res != 0) {

return res;

}

return other.compare(o1, o2);

}

};

return comparator;

}

/**

* 返回一个逆序规则

*/

public static > Comparator reverseOrder() {

return Collections.reverseOrder();

}

/**

* 返回一个正常的排序规则

*/

@SuppressWarnings("unchecked")

public static > Comparator naturalOrder() {

return (Comparator) Comparators.NaturalOrderComparator.INSTANCE;

}

/**

* 返回一个允许null存在的比较器,这个比较器认为null值比非null值小。如果两个比较值都是null,那么认定为相等。

* 如果都不是null,那么按正常的逻辑比较。如果传入的比较器为null,那么认为所有非null值相等

*/

public static Comparator nullsFirst(Comparator super T> comparator) {

return new Comparators.NullComparator<>(true, comparator);

}

/**

* 返回一个允许null存在的比较器,这个比较器认为null值比非null值大。如果两个比较值都是null,那么认定为相等。

* 如果都不是null,那么按正常的逻辑比较。如果传入的比较器为null,那么认为所有非null值相等

*/

public static Comparator nullsLast(Comparator super T> comparator) {

return new Comparators.NullComparator<>(false, comparator);

}

/**

* 传入处理器Function,返回一个新的比较器。

* 这个新的比较器先使用function处理两个比较值key,再去比较key。

*/

public static > Comparator comparing(

Function super T, ? extends U> keyExtractor)

{

Objects.requireNonNull(keyExtractor);

return (Comparator & Serializable)

(c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));

}

}

应用场景List的排序List list = new ArrayList() {{

add(4);

add(444);

add(3);

add(2);

}};

//按升序排列

list.sort(null);

//按自然排序即升序排列

list.sort(Comparator.naturalOrder());

//按升序的逆序即降序排列,并且允许null值

list.sort(Comparator.nullsLast(Comparator.naturalOrder()).reversed());

//按升序的逆序即降序排列

Collections.sort(list,Comparator.nullsLast(Comparator.naturalOrder()).reversed());

System.out.println(Arrays.toString(list.toArray()));comparing方法public static > Comparator comparing(

Function super T, ? extends U> keyExtractor)

{

Objects.requireNonNull(keyExtractor);

return (Comparator & Serializable)

(c1, c2) -> keyExtractor.apply(c1).compareTo(keyExtractor.apply(c2));

}

该方法是静态方法,传入一个function对象,规则是先用function处理两个比较参数key,再去比较这两个key。方法返回一个比较器,用于覆写比较逻辑。

comparing方法的简单应用:Function f = s -> s * s;

Comparator comparator = Comparator.comparing(f);

int compare = comparator.compare(6, 7);

System.out.println(compare);

//比较的是6*6和7*7,输出-1

高级应用Comparator comparing = Comparator.comparing(Integer::intValue);

System.out.println(comparing.compare(3,43));

//比较的是3和43,输出-1

//上面的Integer如果换成普通对象,一样可以使用,例如对象DevelopDoc中包含getCreateTime()方法。

List docs=allDocs;

Collections.sort(docs, Comparator.comparing(DevelopDoc::getCreateTime));

这里要提到的是“::”这个关键字,属于java8的新特性,我们可以通过 :: 关键字来访问类的构造方法,对象方法,静态方法。那么如何访问其中的方法呢?我们先定义一个接口:@FunctionalInterface

static interface Te {

R apply(T t);

}

@FunctionalInterface注解的作用是,限定该接口只能有一个可实现方法,其实不加此注解也没问题,只要不超过1个可实现方法就行,default和static方法不在范畴中。该接口定义了一个入参为T,返回为R的apply方法。我们可以这样使用它,Te t = s -> s + s;

System.out.println(t.apply(100));

//100+100, 输出200

也可以这样使用,//intValue()是Integer类的方法

Te test = Integer::intValue;

System.out.println(test.apply(100));

//输入100,输出200

java 比较器comparator_Java比较器之Comparable 和 Comparator相关推荐

  1. java 比较器comparator_Java中比较器的使用Compare和Comparator

    Comparable和Comparator接口都是为了对类进行比较,众所周知,诸如Integer,double等基本数据类型,java可以对他们进行比较,而对于类的比较,需要人工定义比较用到的字段比较 ...

  2. 分别用Comparable和Comparator两个接口对下列四位同学的成绩做降序排序,如果成绩一样, 那在成绩排序的基础上按照年龄由小到大排序。 姓名(String

    代码 import java.util.*;/*3.分别用Comparable和Comparator两个接口对下列四位同学的成绩做降序排序,如果成绩一样,那在成绩排序的基础上按照年龄由小到大排序.姓名 ...

  3. Java核心API -- 7(Iterator迭代器、Comparable、Comparator比较器)

    1. Iterator迭代器 所有Collection的实现类都实现了iterator方法,该方法返回一个Iterator接口类型的对象,用于实现对集合元素迭代的便利.在java.util包下. 1) ...

  4. Java比较器-Comparable和Comparator

    Comparable This interface imposes a total ordering on the objects of each class that implements it. ...

  5. JAVA语言-比较器Comparator(java中Comparable和Comparator的区别)

    文章目录 一.什么是Comparator 二.Java compare方法和compareTo方法 三.java中Comparable和Comparator的区别 Comparator的例子 三.de ...

  6. Java 中 Comparable 和 Comparator 比较

    为什么80%的码农都做不了架构师?>>>    本文,先介绍Comparable 和Comparator两个接口,以及它们的差异:接着,通过示例,对它们的使用方法进行说明. Comp ...

  7. Java中Comparable和Comparator区别小结

    阅读目录 一.Comparable简介 二.Comparator简介 三.Comparable和Comparator区别比较 回到顶部 一.Comparable简介 Comparable是排序接口.若 ...

  8. Java中Comparable与Comparator的区别

    一.概述 Comparable和Comparator都是用来实现集合中元素的比较.排序的. Comparable是在集合内部定义的方法实现的排序,位于java.util下. Comparator是在集 ...

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

    本文要来详细分析一下Java中Comparable和Comparator接口的区别,两者都有比较的功能,那么究竟有什么区别呢,感兴趣的Java开发者继续看下去吧. Comparable 简介 Comp ...

最新文章

  1. 国产AI芯片加速,鲲云携手浪潮推出数据流AI服务器
  2. C# SerialPort 读写三菱FX系列PLC
  3. WebAssembly,开发者赢了
  4. Java福尔摩斯的约会大侦探福尔摩斯接到一张奇怪的字条:“我们约会吧 3485djDkxh4hhGE 2984akDfkkkkggEdsb shgsfdk dHyscvnm”。大侦探很快就明白了
  5. java小程序小游戏代码贪吃蛇,附高频面试题合集
  6. 接口,new,匿名内部类
  7. SpringCloud工作笔记040---zuul网关集合springsecurity_JWT 颁发token_但是Authorization无法传递到response的header中
  8. cosin等于多少_cos0等于多少?
  9. 野人岛华娱java下载_华娱又携惊喜—《野人岛4—四季神器》评测!
  10. Python压缩、减压7z文件
  11. Xprivacy - 必须拥有黑客应用程序
  12. 这5个摸鱼神器太火了!程序员:知道了快删!
  13. JAVA动态桌面制作_自己动手制作安卓动态壁纸教
  14. VScode常用插件(C/C++开发)
  15. 电机集电环是如何更换与运行的
  16. hadoop的单机版测试和集群节点的搭建
  17. 老计算机u盘无法启动不了怎么办,u盘无法启动怎么办 u盘无法启动解决方法【详解】...
  18. python学习每日一题【20200226】python实现“分解质因数”的计算
  19. 基于Python回归模型的异方差性分析
  20. mysql中双引号和单引号有什么区别

热门文章

  1. 禅与 Objective-C 编程艺术
  2. 多线程与高并发(四)
  3. 仿微信实现添加联系人
  4. CentOS安装配置Java环境
  5. Linux6.5双网卡绑定重启网络异常,Centos 6.5 64位双网卡绑定教程
  6. 使用 Prettier 美化你的代码
  7. 智能触控平板如何选? MAXHUB X3 SC65CD双十一促销
  8. 基于JAVA的新闻发布管理系统开发参考【数据库设计、源码、开题报告】
  9. (简易SSM框架搭建)物流查询系统
  10. 自学古筝五年后的心得总结(陆续更新中)