先定义一个实体类

@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排序的更多相关文章

  1. Lambda表达式, 可以让我们的代码更优雅.

    在C#中, 适当地使用Lambda表达式, 可以让我们的代码更优雅. 通过lambda表达式, 我们可以很方便地创建一个delegate: 下面两个语句是等价的 Code highlighting p ...

  2. JDK8漫谈——代码更优雅

    简介 lambda表达式,又称闭包(Closure)或称匿名方法(anonymous method).将Lambda表达式引入JAVA中的动机源于一个叫"行为参数"的模式.这种模式 ...

  3. 用Assert(断言)封装异常,让代码更优雅(附项目源码)

    有关Assert断言大家并不陌生,我们在做单元测试的时候,看业务事务复合预期,我们可以通过断言来校验,断言常用的方法如下: public class Assert { /** * 结果 = 预期 则正 ...

  4. CSS 黑魔法小技巧,让你少写不必要的JS,代码更优雅

    首页   登录注册         CSS 黑魔法小技巧,让你少写不必要的JS,代码更优雅 阅读 8113 收藏 927 2017-09-26 原文链接:github.com 腾讯云容器服务CSS,立 ...

  5. 【原创】基于.NET的轻量级高性能 ORM - TZM.XFramework 之让代码更优雅

    [前言] 大家好,我是TANZAME.出乎意料的,我们在立冬的前一天又见面了,天气慢慢转凉,朋友们注意添衣保暖,愉快撸码.距离 TZM.XFramework 的首秀已数月有余,期间收到不少朋友的鼓励. ...

  6. 使用Object#tap使代码更优雅

    今天看spree源码的时候经常看到Object#tap方法.以前只知道有这个方法,而且感觉这个方法调试的作用大于实际,今日看来以前的理解应该不够准确. 先看下官方文档上tap的例子 Yields se ...

  7. 【转】Lombok:让JAVA代码更优雅

    原文地址:http://blog.didispace.com/java-lombok-1/ 关于Lombok,其实在网上可以找到很多如何使用的文章,但是很少能找到比较齐全的整理.我也一直寻思着想写一篇 ...

  8. 分享几个简单的技巧让你的 vue.js 代码更优雅

    1. watch 与 computed 的巧妙结合 一个简单的列表页面. 你可能会这么做: created(){ this.fetchData() }, watch: { keyword(){ thi ...

  9. 妙用ES6解构和扩展运算符让你的代码更优雅

    http://www.cnblogs.com/chrischjh/p/4848934.html

随机推荐

  1. .NetCore 分页控件实现原理处理以及条件分页处理

    说明 自定义一个类继承TagHelper,注意自定义类的 必须以TagHelper结尾,这个有点类是属性 Attribute的写法 protected TagHelper(); // // 摘要: / ...

  2. .NetCore Cap 结合 RabbitMQ 实现消息订阅

    开源分布式消息框架 Cap 可以在GitHub上拉也可以通过nuget添加 上一篇博文写了 Windows RabbitMQ的安装使用 Cap支持事务,通过捕获数据库上下文连接对象实现 消息事务,消息 ...

  3. Codeforces 379F New Year Tree 树的直径的性质推理

    New Year Tree 我们假设当前的直径两端为A, B, 那么现在加入v的两个儿子x, y. 求直径的话我们可以第一次dfs找到最远点这个点必定为直径上的点, 然而用这个点第二次dfs找到最远点 ...

  4. 利用 gdb 探究main(int argc, char *argv[]){} 中的char *argv[]

    在 Linux 系统中编写小程序 代码如下 编译并采用gdb调试  在调试之前设置三个参数   a   bb   ccc 输入 start 执行代码到 return 0; 从这里可以看到 argc = ...

  5. Java string.valueof的用法以及与parseint的区别

    一.由基本数据型态转换成String String 类别中已经提供了将基本数据型态转换成 String 的 static 方法 ,也就是 String.valueOf() 这个参数多载的方法 有以下几 ...

  6. odoo权限管理(二.记录管理)

    规则保存在ir.rule模型表里,需要设置关联某个模型,关联很多组,访问权限控制和domian. 通过domain_force过滤出的一些记录来执行约束. 例子:经理只能删除状态为'cancel'的客 ...

  7. bzoj 2809 可并堆维护子树信息

    对于每个节点,要在其子树中选尽量多的节点,并且节点的权值和小于一个定值. 建立大根堆,每个节点从儿子节点合并,并弹出最大值直到和满足要求. /***************************** ...

  8. Educational Codeforces Round 14 D. Swaps in Permutation 并查集

    D. Swaps in Permutation 题目连接: http://www.codeforces.com/contest/691/problem/D Description You are gi ...

  9. Jmeter自定义编写Java代码调用socket通信

    一.前言 最近需要测试一款手机游戏的性能,找不到啥录制脚本的工具,然后,另外想办法.性能测试实际上就是对服务器的承载能力的测试,和各种类型的手机客户端没有啥多大关系,手机再好,服务器负载不了,也不能够 ...

  10. 使用 IntraWeb (8) - 系统模板

    我们可以自定义系统错误模板, 编辑 IWError.html 放到模板文件夹后, 它将替换默认的模板. {在主页面, 这是要模拟一个系统错误} procedure TIWForm1.IWButton1 ...