Java 集合排序策略接口 Comparator
2020/5/20 14:26:40
本文主要是介绍Java 集合排序策略接口 Comparator,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
1. 前言
最近用到了集合排序(基于 Java 8)。现在我能用 Stream 的就用 Stream ,真香!排序可以这么写:
List<People> 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)
比较两个参数的大小, 返回负整数,零,正整数 ,分别代表 o1<o2
、o1=o2
、o1>o2
,通常分别返回 -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 <T, U> Comparator<T> comparing( Function<? super T, ? extends U> keyExtractor, Comparator<? super U> keyComparator) { Objects.requireNonNull(keyExtractor); Objects.requireNonNull(keyComparator); return (Comparator<T> & 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<People, Integer> getAge = People::getAge;
第二个参数 keyComparator
就很好理解了,表示使用的比较规则。
对 c1
,c2
按照 第一个参数 keyExtractor
提供的规则进行提取特征,然后第二个参数keyComparator
对这两个特征进行比较。下面的式子其实可以概括为 3.1 的 (x1,x2)-> int
(c1, c2) -> keyComparator.compare(keyExtractor.apply(c1), keyExtractor.apply(c2))
Comparator<T> & Serializable 为 Java 8 新特性:同时满足这两个类型约束
理解了这个方法后,其它该系列的方法就好理解了,这里不再赘述。目前 comparing
系列方法使用更加广泛。我们举一些例子:
List<People> 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
进行分析和比较它们的不同,敬请关注。
关注公众号:Felordcn 获取更多资讯
个人博客:https://felord.cn
这篇关于Java 集合排序策略接口 Comparator的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-07-08如何在敏捷项目中实现高效测试?
- 2024-07-08用户故事一定要有 “So that...” 吗?
- 2024-07-04TiDB 资源管控的对撞测试以及最佳实践架构
- 2024-07-03万字长文聊聊Web3的组成架构
- 2024-07-02springboot项目无法注册到nacos-icode9专业技术文章分享
- 2024-06-26结对编程到底难不难?答案在这里
- 2024-06-19《2023版Java工程师》课程升级公告
- 2024-06-15matplotlib作图不显示3D图,怎么办?
- 2024-06-1503-Loki 日志监控
- 2024-06-1504-让LLM理解知识 -Prompt