Java8 Comparator源码演示及解析

在前面一篇Java Comparable和Comparator对比详解中,对于java中的排序方法进行比较和具体剖析,主要是针对 Comparator接口和 Comparable接口,无论是哪种方式,都需要实现这个接口,并且重写里面的 方法。

Java8中对其进行了优化,直接调用Comparator类即可实现一些自定义的排序功能,比如按照某个字段升序,并且按照某个字段降序排列;还有如果出现null 的情况怎么处理等等。下面是针对常见的 基础数据类型的list 和 对象的集合 进行排序的演示。

/**
 * 关于 java8 中的 Comparator 排序方法
 */
public class CompareController2 {

  public static void main(String[] args) {

    /**
     * 对常见的list等进行升序和降序
     */
    List<Integer> list = Arrays.asList(10,133,34,546,53,345);
    // 自然顺序,升序
    list.sort(Comparator.naturalOrder());
    System.out.println(list);
    // 降序
    list.sort(Comparator.reverseOrder());
    System.out.println(list);

    /**
     * 对于 对象的排序
     */
    List<Students> studentsList = new ArrayList<>();
    studentsList.add(new Students("zhangSan", 28, "beiJing"));
    studentsList.add(new Students("liSi", 25, "shangHai"));
    studentsList.add(new Students("wangWu", 22));

    studentsList.sort(Comparator.comparing(Students::getName));
    System.out.println("按照姓名升序:" + studentsList);

    studentsList.sort(Comparator.comparing(Students::getAge).reversed());
    System.out.println("按照年龄降序:" + studentsList);

    studentsList.sort(Comparator.comparing(Students::getAddress, Comparator.nullsLast(String::compareTo)).reversed());
    System.out.println("按照地址降序,若有空,放到最前面:" + studentsList);

    studentsList.sort(Comparator.comparing(Students::getAddress, Comparator.nullsFirst(String::compareTo)).reversed());
    System.out.println("按照地址降序,若有空,放到最后面:" + studentsList);

    studentsList.sort(Comparator.comparing(Students::getAddress, Comparator.nullsLast(String::compareTo)).reversed().thenComparing(Students::getAge));
    System.out.println("按照地址降序,若有空,放到最前面,然后再按照年龄升序:" + studentsList);

  }
}

Comparator的源码解析

最近的学习,让我意识到了看源码的重要性,所以分析完Comparator如何使用后,继续研究源码。

1)首先看下 comparing 的源码,其实就是 compareTo 方法。

2)接下看下 thenComparing 方法,其实就是 compare 方法,和我们实现某个接口并且重写里面的方法类似,只不过 Comparator在底层帮我们实现了。

3)最后来看下比较有趣的 nullsFirst 方法和 nullsLast 方法,两个方法其实主要就是 nullFirst的标志位不同,其底层仍然是 实现 compare方法,只不过加了一个对于null 的判断,还有一个是根据 nullFirst的标志位 的判断。Get !!!

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Java中实现Comparator接口和用法实例(简明易懂)

    在java中,如果要对集合对象或数组对象进行排序,需要实现Comparator接口以达到我们想要的目标. 接下来我们模拟下在集合对象中对日期属性进行排序 一.实体类Step package com.ljq.entity; /** * 运号单流程 * * @author Administrator * */ public class Step{ /** 处理时间 */ private String acceptTime = ""; /** 快件所在地点 */ private String

  • Java函数式编程(九):Comparator

    实现Comparator接口 Comparator接口的身影在JDK库中随处可见,从查找到排序,再到反转操作,等等.Java 8里它变成了一个函数式接口,这样的好处就是我们可以使用流式语法来实现比较器了. 我们用几种不同的方式来实现一下Comparator,看看新式语法的价值所在.你的手指头会感谢你的,不用实现匿名内部类少敲了多少键盘啊. 使用Comparator进行排序 下面这个例子将使用不同的比较方法,来将一组人进行排序.我们先来创建一个Person的JavaBean. 复制代码 代码如下:

  • Java 中Comparable和Comparator区别比较

    Comparable 简介Comparable 是排序接口.若一个类实现了Comparable接口,就意味着"该类支持排序".  即然实现Comparable接口的类支持排序,假设现在存在"实现Comparable接口的类的对象的List列表(或数组)",则该List列表(或数组)可以通过 Collections.sort(或 Arrays.sort)进行排序.此外,"实现Comparable接口的类的对象"可以用作"有序映射(如Tre

  • java比较器comparator使用示例分享

    复制代码 代码如下: import java.util.ArrayList;import java.util.Collections;import java.util.Comparator;import java.util.List; public class ComparatorTest implements Comparator<stuEntity> { /**     * @param args     */    public static void main(String[] arg

  • 详解Java中Comparable和Comparator接口的区别

    详解Java中Comparable和Comparator接口的区别 本文要来详细分析一下Java中Comparable和Comparator接口的区别,两者都有比较的功能,那么究竟有什么区别呢,感兴趣的Java开发者继续看下去吧. Comparable 简介 Comparable 是排序接口. 若一个类实现了Comparable接口,就意味着"该类支持排序".  即然实现Comparable接口的类支持排序,假设现在存在"实现Comparable接口的类的对象的List列表(

  • Java8 Comparator: 列表排序的深入讲解

    在本文中,我们将看到几个关于如何在Java 8中对List进行排序的示例. 1.按字母顺序排序字符串列表 List<String> cities = Arrays.asList( "Milan", "london", "San Francisco", "Tokyo", "New Delhi" ); System.out.println(cities); //[Milan, london, San

  • 对比Java中的Comparable排序接口和Comparator比较器接口

    Comparable Comparable 是排序接口. 若一个类实现了Comparable接口,就意味着"该类支持排序". 即然实现Comparable接口的类支持排序,假设现在存在"实现Comparable接口的类的对象的List列表(或数组)",则该List列表(或数组)可以通过 Collections.sort(或 Arrays.sort)进行排序. 此外,"实现Comparable接口的类的对象"可以用作"有序映射(如Tree

  • 详解JAVA使用Comparator接口实现自定义排序

    1.原则 Comparator接口可以实现自定义排序,实现Comparator接口时,要重写compare方法: int compare(Object o1, Object o2) 返回一个基本类型的整型 如果要按照升序排序,则o1 小于o2,返回-1(负数),相等返回0,01大于02返回1(正数) 如果要按照降序排序,则o1 小于o2,返回1(正数),相等返回0,01大于02返回-1(负数) import java.util.ArrayList; import java.util.Compar

  • Java8 Comparator源码演示及解析

    在前面一篇Java Comparable和Comparator对比详解中,对于java中的排序方法进行比较和具体剖析,主要是针对 Comparator接口和 Comparable接口,无论是哪种方式,都需要实现这个接口,并且重写里面的 方法. Java8中对其进行了优化,直接调用Comparator类即可实现一些自定义的排序功能,比如按照某个字段升序,并且按照某个字段降序排列:还有如果出现null 的情况怎么处理等等.下面是针对常见的 基础数据类型的list 和 对象的集合 进行排序的演示. /

  • vue解析指令compile源码层面使用解析

    目录 概述 compile 测试代码 结果 延伸及重点讲解 1. 类数组对象 2. RegExp.$1 3. nodeType 概述 上篇文章我们已经介绍了Vue的响应式原理,并实现了对数据的监听,监听的目的是为了及时更新视图,所以这篇文章就来介绍下vue解析指令并初始化视图部分. compile 在Vue的构造函数中对根元素进行编译 class MVue { constructor (options) { // 保存options this.$options = options this.$d

  • Java CountDownLatch的源码硬核解析

    目录 前言 介绍和使用 例子 概述 实现思路 源码解析 类结构图 await() 实现原理 countDown()实现原理 前言 对于并发执行,Java中的CountDownLatch是一个重要的类,简单理解, CountDownLatch中count down是倒数的意思,latch则是“门闩”的含义.在数量倒数到0的时候,打开“门闩”, 一起走,否则都等待在“门闩”的地方. 为了更好的理解CountDownLatch这个类,本文通过例子和源码带领大家深入解析这个类的原理. 介绍和使用 例子

  • go kratos源码及配置解析

    目录 相关类图 流程解释 代码案例 相关类图 项目启动时一般前置条件为解析配置文件, 我们看下这块是怎么设计的. 流程解释 config 实现 config Interface 接口, 初始化reader对象 调用Load方法, 通过入口注入的不同文件源, 调用实现了source interface 对应的Load方法(以file举例子) file 通过 Load 入口, 判断是目录还是文件, 执行对应的方法, 拿到文件内容返回 config 拿到file返回的内容, 交给reader去合并 r

  • Spring Aware源码设计示例解析

    目录 1. Aware介绍 2. Aware类别 2.1 BeanClassLoaderAware 2.2 BeanFactoryAware 2.3 BeanNameAware 2.4 ApplicationContextAware 3. Aware的使用 4. Aware的作用 5. Aware的调用 1. Aware介绍 前一篇讲到了BeanPostProcessor的相关知识,我们知道BeanPostProcessor是对整个容器中的Bean做前置和后置增强处理.这样的实现方式限制了开发者

  • JDK源码之PriorityQueue解析

    一.优先队列的应用 优先队列在程序开发中屡见不鲜,比如操作系统在进行进程调度时一种可行的算法是使用优先队列,当一个新的进程被fork()出来后,首先将它放到队列的最后,而操作系统内部的Scheduler负责不断地从这个优先队列中取出优先级较高的进程执行:爬虫系统在执行时往往也需要从一个优先级队列中循环取出高优先级任务并进行抓取.可以想见,如果类似这样的任务不适用优先级进行划分的话,系统必会出现故障,例如操作系统中低优先级进程持续占用资源而高优先级进程始终在队列中等待.此外,优先队列在贪婪算法中也

  • Python Django源码运行过程解析

    目录 一.Django运行顺序 1.启动 1.1 命令行启动(测试服务器) 2.监听 2.1 runserver(测试服务器) 3.中间件的执行 本文只算是本人片面之言(当然也会借鉴网络上公开资料),而且技术含量比较低,内容质量也一般,大家仅限参考即可 如果对本文看不太懂,请先阅读后面文章,等都差不多看完再回顾来看 一.Django运行顺序 WSGI会不断监听客户端发送来的请求 先经过中间件进行分析验证处理 然后经过url分发与验证 视图层进行处理 再经过中间件进行分析验证处理 返回响应内容 1

  • android异步消息机制 源码层面彻底解析(1)

    Handler.Message.Loopler.MessageQueen 首先看一下我们平常使用Handler的一个最常见用法. Handler handler =new Handler(){ @Override public void handleMessage(Message msg) { super.handleMessage(msg); //这里进行一些UI操作等处理 } new Thread(new Runnable() { @Override public void run() {

  • Andorid jar库源码Bolts原理解析

    Bolts: 作用: 用于链式执行跨线程代码,且传递数据 栗子: 复制代码 Task.call(new Callable<Boolean>() { @Override public Boolean call() throws Exception { return true; } }, Task.UI_THREAD_EXECUTOR); Task.callInBackground(new Callable<Boolean>() { @Override public Boolean c

  • Idea导入eureka源码实现过程解析

    通过GitHub获取Eureka源码 进入git bash命令行,自己找个目录,用来存放eureka源码,然后在目录里面,执行git clone  https://github.com/Netflix/eureka.git,就可以了,这个是需要点时间的,稍微有点慢,你等一会儿好了. git clone https://github.com/Netflix/eureka.git 获取eureka项目依赖 然后在eureka目录中,直接双击gradlew.bat就可以,这个是人家给你提供的命令,直接

随机推荐