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 中如何指定集合元素的排序策略相关推荐

  1. 在Java开发中,判断list集合为空还是为null的区别

    在Java开发中,判断list集合为空还是为null的区别 案例测试1 为什么输出not null,是因为null判断的是否对List集合分配内存空间,为不是List集合里面内容是否为空 案例测试2 ...

  2. pta数据结构实验在数组中查找指定元素_如何从一个数组中查找指定的元素,并返回这个元素在数组中的位置...

    展开全部 和Vector都是使用Objec的数组形式来存储的.当你向这两种类型中增加元素的时候,如果元素的数目超出e68a84e8a2ad62616964757a686964616f313332646 ...

  3. java list_java中的list集合

    Java 集合 java集合概览 几幅图让你认识Java集合 java中List.Array.Map.Set等集合相互转换的最佳方法 关于Java集合最被关注的10 个问题 本列表会不断更新 文章 s ...

  4. Java循环中删除一个列表元素

    本文主要想讲述一下我对之前看到一篇文章的说法.假设跟你的想法有出入,欢迎留言.一起讨论. #3. 在循环中删除一个列表元素 考虑以下的代码.迭代过程中删除元素: ArrayList<String ...

  5. spring中父子bean集合元素合并问题

    spring支持集合核定的功能,允许子bean继承父bean的同名属性集合元素,并将子bean中配置的集合属性值和父bean中配置的同名属性值合并起来作为最终bean的属性值: <bean id ...

  6. List集合中删除指定的元素

    这个问题的坑点在于循环删除掉元素时,后面所有元素的索引都会递减改变,比如循环到第二个元素时执行删除操作,下一次应该循环操作索引为2的元素,可是此时当初索引为2的元素已经移动到索引为1的元素上了,也就是 ...

  7. 【python】list 删除列表中某个元素的3种方法;附加删除numpy数组中的指定索引元素的方法

    方法 python中关于删除list中的某个元素,一般有三种方法: remove.pop.del 实例 1.remove: 删除单个元素,删除首个符合条件的元素,按值删除 2.pop: 删除单个或多个 ...

  8. java 文件中查找指定的单词,查找指定文本文件中的单词数的Java程序

    查找指定文本文件中的单词数的Java程序 1 说明 在此程序中,我们需要找到给定文本文件中出现次数最多的单词.这可以通过使用文件指针以读取模式打开文件来完成.逐行读取文件.一次分割一行并存储在数组中. ...

  9. java long拼接,String类型集合元素分割和拼接,String类型集合转为Long类型集合

    String类型集合中元素拼接为字符串与字符串分割组成数组: List list = new ArrayList<>(); String a= "张三,李四"; Str ...

最新文章

  1. java和python的比较-java和python的比较
  2. 强大的SPGridView
  3. 【C++ Primer】自己动手编写函数 atoi(char *str)
  4. Nmap中文手册浅析
  5. IBM-X3650 6核处理器安装sql server 2005报错解决方法
  6. php字符串对象,PHP字符串到对象名称
  7. (王道408考研数据结构)第三章栈和队列-第三节1:栈的应用之括号匹配问题和表达式问题(前缀、中缀和后缀)
  8. 20155322 《Java程序设计》课堂实践项目 数据库-3-4
  9. MyBatis多参数传递之混合方式——MyBatis学习笔记之十五
  10. python中字典添加元素、其位置在哪里_如何在python字典中添加元素
  11. 浅谈系统如何对接社交登录之微博登录功能
  12. POI dataFormat种类
  13. 定时执行Python程式
  14. 原生android ui设计,在拟物和扁平之间寻找平衡:原生安卓UI设计进化史
  15. 橙色——网页效果图设计之色彩索引
  16. python实现mysql多条件查询筛选功能
  17. CSS基础五(盒模型)
  18. Synchronized锁升级:无锁-> 偏向锁 -> 轻量级锁 -> 重量级锁
  19. Kal系统学习:记录一次wifi破解过程
  20. JAVA编写PTA(10分)

热门文章

  1. 南农计算机分数线,南京农业大学
  2. 河南派出所犯罪嫌疑计算机网络人,【出彩河南公安人】息县公安局冯振娇:平凡岗位献青春 恒心不改展风采...
  3. 【B站视频笔记】linux 进程间通信(ipc)信号(软中断信号)signal库函数、可靠信号和不可靠信号、信号集sigprocmask(信号掩码、信号递达Delivery、信号未决Pending)
  4. C++内联 inline的用法
  5. PIL image.fromarray()函数
  6. 什么是序列化?python pickle模块
  7. Unfair contest 模拟-分类讨论
  8. java正则表达式替换指定字符串_笔记_正则表达式替换字符串中特定范围内的字符。...
  9. Idea控制台中文乱码解决方案
  10. CentOS7下Hadoop集群搭建