1. 前言

最近用到了集合排序(基于 Java 8)。现在我能用 Stream 的就用 Stream ,真香!排序可以这么写:

List peoples = new ArrayList<>();  // 中间省略  // 按照年龄从小到大排序peoples.sort(Comparator.comparing(People::getAge));

这里排序用到了一个关键接口 java.util.Comparator。排序比较作为业务中经常出现的需求,我们有必要研究一下这个接口。

2. Comparator 概念

Comparator 是一个函数式接口。它经常用于没有天然排序的集合进行排序,如 Collections.sort 或 Arrays.sort。或者对于某些有序数据结构的排序规则进行声明,如 TreeSet 、TreeMap 。也就是该接口主要用来进行集合排序。

3. Comparator 中的方法

Comparator 作为一个函数式接口只有一个抽象方法,但是它有很多的默认方法,我们来认识一下这些方法们。

3.1 compare 抽象方法

作为Comparator 唯一的抽象方法,int compare(T o1,T o2) 比较两个参数的大小, 返回负整数,零,正整数 ,分别代表 o1o2,通常分别返回 -1、0 或 1。伪表达式:

// 输入两个同类型的对象 ,输出一个比较结果的int数字(x1,x2)-> int

实现该方法一定要注意以下事项:

  • 必须保证compare(x,y) 和compare(y,x) 的值的和必须为 0
  • 必须保证比较的顺序关系是可传递的,如果compare(x,y)>0 而且compare(y,z)>0 则 compare(x,z)>0。
  • 如果存在 compare(x,y)=0,则对于 z 而言,存在 compare(x, z)==compare(y, z)。

然而并不 严格要求(compare(x, y)==0) == (x.equals(y))。一般说来,任何违背这个条件的 Comparator 实现都应该明确指出这一事实情况。

3.2 comparing 系列方法

Java 8 开始,Comparator 提供了一系列的静态方法,并通过函数式的风格赋予 Comparator 更加强大和方便的功能,我们暂且称它们为 comparing系列方法。

   public static  Comparator comparing(            Function super T, ? extends U> keyExtractor,            Comparator super U> keyComparator)    {        Objects.requireNonNull(keyExtractor);        Objects.requireNonNull(keyComparator);        return (Comparator & Serializable)            (c1, c2) -> keyComparator.compare(keyExtractor.apply(c1),                                              keyExtractor.apply(c2));    }

该方法是该系列方法的基本方法。是不是看上去很难懂的样子?我们来分析一下该方法。它一共两个参数都是函数式接口。

第一个参数 Function super T, ? extends U> keyExtractor 表示输入一个是 T 类型对象,输出一个 U 类型的对象,举个例子,输入一个 People 对象返回其年龄 Integer 数值:

//   people -> people.getAge(); 转换为下面方法引用Function getAge = People::getAge;

第二个参数 keyComparator就很好理解了,表示使用的比较规则。

对 c1,c2 按照 第一个参数 keyExtractor 提供的规则进行提取特征,然后第二个参数keyComparator对这两个特征进行比较。下面的式子其实可以概括为 3.1 的 (x1,x2)-> int

(c1, c2) -> keyComparator.compare(keyExtractor.apply(c1),                                              keyExtractor.apply(c2))

Comparator & Serializable 为 Java 8 新特性:同时满足这两个类型约束

理解了这个方法后,其它该系列的方法就好理解了,这里不再赘述。目前 comparing 系列方法使用更加广泛。我们举一些例子:

List peoples = new ArrayList<>();//  ………………// 按照年龄从低到高排序peoples.sort(Comparator.comparing(People::getAge));// 按照年龄从高到低排序peoples.sort(Comparator.comparing(People::getAge, (x, y) -> -x.compareTo(y)));

同样你可以使用 java.util.Collections 或者 Stream 提供的排序方法来使用Comparator。

4. 小结

今天对 Comparator进行了简单的分析,它用于构建集合排序的规则,在日常开发中非常有用。下一篇 我们将对另一个和它十分相似的接口 Comparable 进行分析和比较它们的不同,敬请关注。

java comparator_Java 集合排序策略接口 Comparator相关推荐

  1. java comparator排序顺序_Java 集合排序策略接口 Comparator

    1. 前言 最近用到了集合排序(基于 Java 8).现在我能用 Stream 的就用 Stream ,真香!排序可以这么写: List<People> peoples = new Arr ...

  2. 2021-06-19复习java Collection集合 Iterator接口_迭代器 增强for循环 泛型

    2021-06-19复习java Collection集合 Iterator接口_迭代器 增强for循环 泛型 Collection集合 java.util.coLlection接口 所有单列集合的最 ...

  3. Java基础—集合2Set接口和Map接口

    第一讲 Set 一 概述 Set:1. 元素存储无下标,所以元素是无序(存入和取出的顺序不一定一致) 2. 元素不可以重复 |--HashSet:底层数据结构是哈希表.线程不同步. 保证元素唯一性的原 ...

  4. java hashedmap_Java基础 - Map接口的实现类 : HashedMap / LinkedHashMap /TreeMap 的构造/修改/遍历/ 集合视图方法/双向迭代输出...

    import java.util.*; /**一:Collection接口的 * Map接口: HashMap(主要实现类) : HashedMap / LinkedHashMap /TreeMap ...

  5. Java中的冒泡排序,Comparator接口和Comparable接口的简单使用

    冒泡排序 冒泡排序是一种常见的排序方法,按照一定的规则(比如从小到大或者从大到小的顺序)对一组数据进行排序.而在Java开发中,也经常用到冒泡排序.我们就以下面的一个例子来讲解冒泡排序算法. 给定一个 ...

  6. java list 接口_Java 集合 List接口

    [TOC] List接口 概述有序的 collection(也称为序列).此接口的用户可以对列表中每个元素的插入位置进行精确地控制.用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的 ...

  7. java list 在头部添加6_【Java提高十六】集合List接口详解

    在编写java程序中,我们最常用的除了八种基本数据类型,String对象外还有一个集合类,在我们的的程序中到处充斥着集合类的身影!java中集合大家族的成员实在是太丰富了,有常用的ArrayList. ...

  8. Java集合Collection接口中的常用方法演示

    Java集合Collection接口中的常用方法演示 添加 add(Objec tobj) 和 addAll(Collection coll) 获取有效元素的个数 int size() 清空集合 vo ...

  9. java之集合Collection之List接口总结

    总结自韩顺平老师的零基础30天学 JAVA 目录 一.集合的框架体系 1.java的集合体系主要可分为两大类:Collection和Map集合. 2.Collection和Map的区别 二.Colle ...

最新文章

  1. 一起学设计模式 - 观察者模式
  2. R构建朴素贝叶斯分类器(Naive Bayes Classifier)
  3. sh文件启动java_shell java应用启动脚本(app.sh)
  4. 什么是伪静态?SEO中如何理解伪静态?
  5. C语言字符串怎么算char字符,计算C中字符串中char的出现次数
  6. iOS开发常用的第三方
  7. 使用Java将项目插入DynamoDB表
  8. mesh 协调器 路由器_关于Mesh网络中,协调器和路由器之间的几个问题?
  9. “刚毕业1年,做Python挣了60W!”网友:吹的不多..
  10. piblog 0.1
  11. cocos2dx windows phone平台下CCLabelTTF自己主动换行的实现
  12. Java中的private、protected、public和default的区别
  13. java db4o 教程_面向Java开发人员db4o指南:数组和集合 (1)
  14. android变化HOLO对话风格
  15. 循环日程表递归法c语言,分治与递归——循环赛日程表
  16. C语言编程统计八皇后问题的解的个数,八皇后问题C语言解法
  17. StreamWiki: Enabling Viewers of Knowledge SharingLive Streams to Collaboratively Generate Archival
  18. echart 正负图
  19. 我是那个逼走创业合伙人的CEO,我有话说!
  20. 如何给孩子选绘本:绘本筛选实践分享

热门文章

  1. python爬取抖音评论_爬取抖音299w用户数据后的分析
  2. 动态改变eachers图表高_动态Excel图表,让数据说话
  3. 网站域名过户查询_聚查教你怎么用域名批量查询工具查询网站历史和域名权重...
  4. 通过phpmyadmin确认此版本的php支持mssql函数,Php5.6.4+IIS8.5+mysql5.6.22+phpmyadmin4.3.6的配置...
  5. ubuntu openssl_在Ubuntu下安装旧版seurat
  6. Log4j 配置的webAppRootKey参数问题
  7. 总结几个经典的java陷阱给大家。
  8. RPM中SPEC宏定义对应路径
  9. 编译报错:make: *** No rule to make target (例如:starg.h)解决
  10. adb devices报错:* daemon not running. starting it now on port 5037(端口未被占用)解决