JAVA8-让代码更优雅之List排序
先定义一个实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Human {
private String name;
private int age;
}
下面的操作都基于这个类来进行操作。这里面使用了Lombok类库,它用注解的方式实现了基本的get和set等方法,让代码看起来更加的优雅。
JAVA8之前的List排序操作
在Java8之前,对集合排序只能创建一个匿名内部类
new Comparator<Human>() {
@Override
public int compare(Human h1, Human h2) {
return h1.getName().compareTo(h2.getName());
}
}
下面是简单的对Humans进行排序(按名称正序)
@Test
public void testSortByName_with_plain_java() throws Exception {
ArrayList<Human> humans = Lists.newArrayList(
new Human("tomy", 22),
new Human("li", 25)
);
Collections.sort(humans, new Comparator<Human>() {
public int compare(Human h1, Human h2) {
return h1.getName().compareTo(h2.getName());
}
});
Assert.assertThat(humans.get(0), equalTo(new Human("li", 25)));
}
使用Lambda的List排序
使用JAVA8函数式方式的比较器
(Human h1, Human h2) -> h1.getName().compareTo(h2.getName())
下面是使用JAVA8函数式的比较的例子
@Test
public void testSortByName_with_lambda() throws Exception {
ArrayList<Human> humans = Lists.newArrayList(
new Human("tomy", 22),
new Human("li", 25)
);
humans.sort((Human h1, Human h2) -> h1.getName().compareTo(h2.getName()));
Assert.assertThat("tomy", equalTo(humans.get(1).getName()));
}
没有类型定义的排序
对于上面的表达式还可以进行简化,JAVA编译器可以根据上下文推测出排序的类型:
(h1, h2) -> h1.getName().compareTo(h2.getName())
简化后的比较器是这样的:
@Test
public void testSortByNameSimplify_with_lambda() throws Exception {
ArrayList<Human> humans = Lists.newArrayList(
new Human("tomy", 22),
new Human("li", 25)
);
humans.sort((h1, h2) -> h1.getName().compareTo(h2.getName()));
Assert.assertThat("tomy", equalTo(humans.get(1).getName()));
}
使用静态方法引用
JAVA8还可以提供使用Lambda表达式的静态类型引用,我们在Human类增加一个静态比较方法,如下:
public static int compareByNameThenAge(Human h1, Human h2) {
if (h1.getName().equals(h2.getName())) {
return Integer.compare(h1.getAge(), h2.getAge());
}
return h1.getName().compareTo(h2.getName());
}
然后就可以在humans.sort使用这个引用
@Test
public void testSort_with_givenMethodDefinition() throws Exception {
ArrayList<Human> humans = Lists.newArrayList(
new Human("tomy", 22),
new Human("li", 25)
);
humans.sort(Human::compareByNameThenAge);
Assert.assertThat("tomy", is(equalTo(humans.get(1).getName())));
}
使用单独的Comparator
JAVA8已经提供了很多方便的比较器供我们使用,比如Comparator.comparing方法,所以可以使用Comparator.comparing方法来实现根据Human的name进行比较的操作:
@Test
public void testSort_with_givenInstanceMethod() throws Exception {
ArrayList<Human> humans = Lists.newArrayList(
new Human("tomy", 22),
new Human("li", 25)
);
Collections.sort(humans, Comparator.comparing(Human::getName));
Assert.assertThat("tomy", equalTo(humans.get(1).getName()));
}
反序
JDK8中也提供了一个支持倒序排序的方法方便我们更快的进行倒序
@Test
public void testSort_with_comparatorReverse() throws Exception {
ArrayList<Human> humans = Lists.newArrayList(
new Human("tomy", 22),
new Human("li", 25)
);
Comparator<Human> comparator = (h1, h2) -> h1.getName().compareTo(h2.getName());
humans.sort(comparator.reversed());
Assert.assertThat("tomy", equalTo(humans.get(0).getName()));
}
使用多个条件进行排序
Lambda提供了更复杂的表达式,还可以先对name排序再根据age进行排序:
@Test
public void testSort_with_multipleComparator() throws Exception {
ArrayList<Human> humans = Lists.newArrayList(
new Human("tomy", 22),
new Human("li", 25)
);
Comparator<Human> comparator = (h1, h2) -> {
if (h1.getName().equals(h2.getName())) {
return Integer.compare(h1.getAge(), h2.getAge());
}
return h1.getName().compareTo(h2.getName());
};
humans.sort(comparator.reversed());
Assert.assertThat("tomy", equalTo(humans.get(0).getName()));
}
使用多个条件进行排序-组合的方式
Comparator对这种组合的排序有更优雅实现,从JDK8开始,我们可以使用链式操作进行复合操作来构建更复杂的逻辑:
@Test
public void testSort_with_multipleComparator_composition() throws Exception {
ArrayList<Human> humans = Lists.newArrayList(
new Human("tomy", 22),
new Human("tomy", 25)
);
humans.sort(Comparator.comparing(Human::getName).thenComparing(Human::getAge));
Assert.assertThat(humans.get(0), equalTo(new Human("tomy", 22)));
}
总结
JDK8真的是一个非常值得我们学习的版本,它提供了Lambda表达式,带来了函数式编程的理念,让JAVA代码更优雅。
所有的完整的代码在这里
原文:http://www.cnblogs.com/tomyLi/p/JAVA8rang-dai-ma-geng-you-ya-zhiList-pai-xu.html
JAVA8-让代码更优雅之List排序的更多相关文章
- Lambda表达式, 可以让我们的代码更优雅.
在C#中, 适当地使用Lambda表达式, 可以让我们的代码更优雅. 通过lambda表达式, 我们可以很方便地创建一个delegate: 下面两个语句是等价的 Code highlighting p ...
- JDK8漫谈——代码更优雅
简介 lambda表达式,又称闭包(Closure)或称匿名方法(anonymous method).将Lambda表达式引入JAVA中的动机源于一个叫"行为参数"的模式.这种模式 ...
- 用Assert(断言)封装异常,让代码更优雅(附项目源码)
有关Assert断言大家并不陌生,我们在做单元测试的时候,看业务事务复合预期,我们可以通过断言来校验,断言常用的方法如下: public class Assert { /** * 结果 = 预期 则正 ...
- CSS 黑魔法小技巧,让你少写不必要的JS,代码更优雅
首页 登录注册 CSS 黑魔法小技巧,让你少写不必要的JS,代码更优雅 阅读 8113 收藏 927 2017-09-26 原文链接:github.com 腾讯云容器服务CSS,立 ...
- 【原创】基于.NET的轻量级高性能 ORM - TZM.XFramework 之让代码更优雅
[前言] 大家好,我是TANZAME.出乎意料的,我们在立冬的前一天又见面了,天气慢慢转凉,朋友们注意添衣保暖,愉快撸码.距离 TZM.XFramework 的首秀已数月有余,期间收到不少朋友的鼓励. ...
- 使用Object#tap使代码更优雅
今天看spree源码的时候经常看到Object#tap方法.以前只知道有这个方法,而且感觉这个方法调试的作用大于实际,今日看来以前的理解应该不够准确. 先看下官方文档上tap的例子 Yields se ...
- 【转】Lombok:让JAVA代码更优雅
原文地址:http://blog.didispace.com/java-lombok-1/ 关于Lombok,其实在网上可以找到很多如何使用的文章,但是很少能找到比较齐全的整理.我也一直寻思着想写一篇 ...
- 分享几个简单的技巧让你的 vue.js 代码更优雅
1. watch 与 computed 的巧妙结合 一个简单的列表页面. 你可能会这么做: created(){ this.fetchData() }, watch: { keyword(){ thi ...
- 妙用ES6解构和扩展运算符让你的代码更优雅
http://www.cnblogs.com/chrischjh/p/4848934.html
随机推荐
- K8S Dashborad登陆认证文档
K8S Dashboard是官方的一个基于WEB的用户界面,专门用来管理K8S集群,并可展示集群的状态.因为我们使用kubeadm搭建的集群会默认开启RABC(角色访问控制机制),所以我们必须要进行额 ...
- Linux系统运维笔记(一),查看系统版本和设置系统时间
Linux系统运维笔记 查看系统版本和设置系统时间 查看系统版本 lsb_release -a (适用于所有的linux,包括Redhat.SuSE.Debian等发行版,但是在debian下要安装l ...
- yum源安装php报错缺少libmcrypt.so.4()(64bit)库
https://blog.csdn.net/programercch/article/details/56282184
- word2vec中的数学原理一 目录和前言
最近在看词向量了,因为这个概念对于语言模型,nlp都比较重要,要好好的学习一下.把网上的一些资料整合一下,搞个系列. 主要参考: word2vec 中的数学原理详解 ...
- spring boot + vue + element-ui
spring boot + vue + element-ui 一.页面 1.布局 假设,我们要开发一个会员列表的页面. 首先,添加vue页面文件“src\pages\Member.vue” 参照文档h ...
- video.js视频播放器
免费视频播放器videojs中文教程 Video.js是一款web视频播放器,支持html5和flash两种播放方式.更多关于video.js的介绍,可以访问官方网站介绍,我之前也写过一篇关于vide ...
- 【BZOJ】3456: 城市规划(多项式求ln)
题解 在我写过分治NTT,多项式求逆之后 我又一次写了多项式求ln 我们定义一个数列的指数型生成函数为 \(\sum_{i = 0}^{n} \frac{A_{i}}{i!} x^{i}\) 然后这个 ...
- 【BZOJ】4560: [JLoi2016]字符串覆盖
题解 先用kmp求出来一个ed[i][j]表示在母串的第i位是第j个子串的结尾 考虑状压一个二进制位表示这个子串覆盖过没有 对于最大值,记一个dp[S][i]表示子串的使用状况为S,当前为母串的第i位 ...
- js+ajax+springmvc实现无刷新文件上传
话不多说直接上代码 <%@ page language="java" contentType="text/html; charset=UTF-8" pag ...
- streaming优化:禁用序列化
如果你的streaming处理数据的时间间隔比较小,并且没有窗口操作,那么可以考虑不使用序列化,这样可以减少内存和cpu的使用,加快数据处理效率