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
随机推荐
- KnockoutJs学习笔记(九)
由于component binding部分的内容更为复杂一些,所以这部分我暂时跳过,先学习click binding部分. click binding不仅可以作用于button.input.a等元素, ...
- ***文件上传控件bootstrap-fileinput的使用和参数配置说明
特别注意: 引入所需文件后页面刷新查看样式奇怪,浏览器提示错误等,可能是因为js.css文件的引用顺序问题,zh.js需要在fileinput.js后面引入.bootstrap最好在filein ...
- Vue.Js的用户体验优化
一次基于Vue.Js的用户体验优化 一.写在前面 半年以前,第一次在项目上实践VueJs,由于在那之前,没有Angular,avalon等框架的实践经验,所以在Vue的使用上,没有给自己总结出更多 ...
- 002 jquery基本选择器
1.选择器 2.基本选择器 3.程序(包含以上五种基本选择器) <!DOCTYPE html> <html> <head> <meta charset=&qu ...
- ref:linux查看用户登录时间以及命令历史
ref:https://blog.csdn.net/csdn924618338/article/details/73555725/ 1.查看当前登录用户信息 who命令: who缺省输出包括用户名.终 ...
- auth.User.groups: (fields.E304)
配置用户信息的models时,如果继承Abstractuser类时,报错: ERRORS:auth.User.groups: (fields.E304) Reverse accessor for 'U ...
- gson Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path
返回数据解析错误 com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT ...
- [USACO3.2]Sweet Butter
题目大意: 给定一张$k$个结点,$m$条边的无向图,其中有$n$个点被标记,在这$k$个点中找出一个点使得这个点到那$n$个点的最短距离之和最小,求出这个距离和. 思路: 对于每个标记结点跑最短路, ...
- 【Codeforces666E】Forensic Examination 后缀自动机 + 线段树合并
E. Forensic Examination time limit per test:6 seconds memory limit per test:768 megabytes input:stan ...
- ELASTIC的备份与恢复
前言 elasticsearch官方并没有提供合适的备份工具,然而生产场景中备份却是的确需要的. 本文介绍了使用自己写的php脚本以及第三方工具来进行索引的备份,恢复以及删除等操作. 全量备份 ela ...