Java 8 Friday Goodies:Lambda和排序

在Data Geekery ,我们喜欢Java。 而且,由于我们真的很喜欢jOOQ的流畅的API和查询DSL ,我们对Java 8将为我们的生态系统带来什么感到非常兴奋。 我们已经写了一些关于Java 8好东西的博客 ,现在我们觉得是时候开始一个新的博客系列了……

Java 8星期五

每个星期五,我们都会向您展示一些不错的教程风格的Java 8新功能,这些功能利用了lambda表达式,扩展方法和其他好东西。 您可以在GitHub上找到源代码 。

Java 8 Goodie:Lambda和排序

排序数组和集合是Java 8 lambda表达式的绝佳用例,原因很简单,因为Comparator自从JDK 1.2引入以来一直一直是@FunctionalInterface 。 现在,我们可以将lambda表达式形式的Comparators提供给各种sort()方法。

对于以下示例,我们将使用此简单的Person类:

static class Person {final String firstName;final String lastName;Person(String firstName, String lastName) {this.firstName = firstName;this.lastName = lastName;}@Overridepublic String toString() {return "Person{" +"firstName='" + firstName + '\'' +", lastName='" + lastName + '\'' +'}';}
}

显然,我们也可以通过使它实现Comparable来向Person添加自然排序,但让我们关注外部Comparators 。 考虑以下Person列表,其名称是使用一些在线随机名称生成器生成的:

List<Person> people =
Arrays.asList(new Person("Jane", "Henderson"),new Person("Michael", "White"),new Person("Henry", "Brighton"),new Person("Hannah", "Plowman"),new Person("William", "Henderson")
);

我们可能想按姓氏然后按名字对它们进行排序。

用Java 7排序

这样的Comparator器的一个“经典” Java 7示例是这样的:

people.sort(new Comparator<Person>() {@Overridepublic int compare(Person o1, Person o2) {int result = o1.lastName.compareTo(o2.lastName);if (result == 0)result = o1.firstName.compareTo(o2.firstName);return result;}
});
people.forEach(System.out::println);

以上将产生:

Person{firstName='Henry', lastName='Brighton'}
Person{firstName='Jane', lastName='Henderson'}
Person{firstName='William', lastName='Henderson'}
Person{firstName='Hannah', lastName='Plowman'}
Person{firstName='Michael', lastName='White'}

用Java 8排序

现在,让我们将以上内容翻译为等效的Java 8代码:

Comparator<Person> c = (p, o) ->p.lastName.compareTo(o.lastName);c = c.thenComparing((p, o) ->p.firstName.compareTo(o.firstName));people.sort(c);
people.forEach(System.out::println);

结果显然是相同的。 如何阅读以上内容? 首先,我们将lambda表达式分配给本地Person Comparator变量:

Comparator<Person> c = (p, o) ->p.lastName.compareTo(o.lastName);

与Scala,C#或Ceylon不同,后者通过val关键字(或类似关键字) 知道从表达式到局部变量声明的类型推断,而Java从变量(或参数,成员)声明到要分配的表达式执行类型推断。

换句话说,类型推断是从“左到右”而不是从“右到左”执行的。 这使得链接Comparators有点麻烦,因为Java编译器在将比较器传递给sort()方法之前不能延迟lambda表达式的类型推断 。

但是,一旦为变量分配了Comparator ,就可以通过thenComparing()流畅地链接其他比较器:

c = c.thenComparing((p, o) ->p.firstName.compareTo(o.firstName));

最后,我们将其传递给List的新sort()方法,这是直接在List接口上实现的默认方法:

default void sort(Comparator<? super E> c) {Collections.sort(this, c);
}

上述限制的解决方法

虽然Java的类型推断“局限性”可能会让人感到沮丧,但我们可以通过创建通用的IdentityComparator解决类型推断:

class Utils {static <E> Comparator<E> compare() {return (e1, e2) -> 0;}
}

使用上面的compare()方法,我们可以编写以下流畅的比较器链:

people.sort(Utils.<Person>compare().thenComparing((p, o) -> p.lastName.compareTo(o.lastName)).thenComparing((p, o) -> p.firstName.compareTo(o.firstName))
);people.forEach(System.out::println);

提取密钥

这可以变得更好。 由于我们通常会比较两个Comparator参数的相同POJO / DTO值,因此我们可以通过“键提取器”功能将它们提供给新的API。 它是这样工作的:

people.sort(Utils.<Person>compare().thenComparing(p -> p.lastName).thenComparing(p -> p.firstName));
people.forEach(System.out::println);

因此,在给定Person p我们为API提供了提取例如p.lastName 。 实际上,一旦我们使用了键提取器,我们就可以省略我们自己的实用程序方法,因为这些库还有一个comparing()方法来初始化整个链:

people.sort(Comparator.comparing((Person p) -> p.lastName).thenComparing(p -> p.firstName));
people.forEach(System.out::println);

同样,我们需要帮助编译器,因为它不能推断所有类型,即使原则上在这种情况下sort()方法将提供足够的信息。 要了解有关Java 8的通用类型推断的更多信息,请参见我们以前的博客文章 。

结论

与Java 5一样,可以在JDK库中看到升级的最大改进。 当Java 5为Comparators带来类型安全性时,Java 8使它们易于读取和编写(给出或接受奇数类型推理怪癖)。

Java 8将彻底改变我们编程的方式,下周,我们将看到Java 8如何影响我们与SQL交互的方式。

参考: Java 8 Friday Goodies:Lambda和Sorting,来自我们的JCG合作伙伴 Lukas Eder在JAVA,SQL和JOOQ博客上。

翻译自: https://www.javacodegeeks.com/2014/02/java-8-friday-goodies-lambdas-and-sorting.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/364618.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

npm 包下载的各种姿势

最近在写Node程序的时候&#xff0c;突然对 npm install 的-save和-save-dev 这两个参数的使用比较混乱。其实博主在这之前对这两个参数的理解也是模糊的&#xff0c;各种查资料和实践后对它们之间的异同点略有理解。遂写下这篇文章避免自己忘记&#xff0c;同时也给node猿友一…

39.数组中数值和下标相等的元素

题目描述&#xff1a; 假设一个单调递增的数组里的每个元素都是整数且是唯一的&#xff0c;请编程实现一个函数&#xff0c;找出数组中任意一个数值等于其下标的元素&#xff0c;例如&#xff0c;在数组{-3&#xff0c;-1,1,3,5}中数字3和它的下标相同。 思路分析&#xff1a; …

php读取xml标签内容,从xml php5获取内容

我正在研究一个支付解决方案,需要一些关于php的帮助。我正在做一个httprequest,作为回应,我将得到一些xml。XML可能如下所示:1description121510authurlsettleurl基本上我想做的是从标签中获取内容并将其保存为字符串。我试过这个:$order <?xml version"1.0" en…

jquery3和layui冲突导,致使用layui.layer.full弹出全屏iframe窗口时高度152px问题

项目中使用的jquery版本是jquery-3.2.1&#xff0c;在使用layui弹出全屏iframe窗口时&#xff0c;iframe窗口顶部总是出现一个152px高的滚动窗口无法实现真正全屏&#xff0c;代码如下&#xff1a; <!DOCTYPE html> <html> <head><meta charset"utf-…

ADF Faces。 立即的自定义客户端事件

在本文中&#xff0c;我将重点介绍ADF Faces Javascript API方法以从客户端触发自定义事件。 例如&#xff1a; function cliListener(actionEvent) {AdfCustomEvent.queue(actionEvent.getSource(), "servListener",null, true);}我们可以使用af&#xff1a;client…

react-native页面间传递数据的几种方式

1. 利用react-native 事件DeviceEventEmitter 监听广播 应用场景&#xff1a; - 表单提交页面&#xff0c; A页面跳转到B页面选人&#xff0c; 然后返回A页面&#xff0c; 需要将B页面选择的数据传回A页面。 - 多个多媒体来回切换播放&#xff0c;暂停后二次继续播放等问题。…

php数据库操作类的调用优化,PHP PDO优化数据库操作类 多数据库驱动类

就是做一下整理 PHP PDO类操作。简化操作流程更多内容http://git.oschina.net/youkuiyuan/yky_test/blob/master/class/pdo.class.php点击链接加入群【微信开发探讨群】&#xff1a;http://jq.qq.com/?_wv1027&kcsNcd9群号&#xff1a;330393916欢迎浏览&#xff1a;www.z…

Genymotion模拟器安装ARM架构编译应用失败解决方案

我们在安装一些应用到Genymotion模拟器会提示&#xff1a;adb: failed to install xx.apk: Failure [INSTALL_FAILED_NO_MATCHING_ABIS: Failed to extract native libraries, res-113] 原因是Genymotion采用的编译方式是x86&#xff0c;默认不支持ARM架构编译的应用&#xff0…

CentOS7.5 yum 安装与配置MySQL5.7.24

安装环境&#xff1a;CentOS7 64位 MINI版&#xff0c;安装MySQL5.7 1、配置YUM源 在MySQL官网中下载YUM源rpm安装包&#xff1a;https://dev.mysql.com/downloads/repo/yum/ 下面已经提供一个YUM源安装包,如果不需要特定版本可直接使用我提供的5.7.24版本 # 下载mysql源安装包…

5种改善服务器日志记录的技术

在最近的时间里&#xff0c;我们已经看到了许多工具可以帮助您理解日志。 诸如Scribe和LogStash之类的开源项目&#xff0c;诸如Splunk之类的本地工具以及诸如SumoLogic和PaperTrail之类的托管服务。 这些都可以帮助您将大量日志数据减少为更有意义的内容。 它们共有一个共同点…

在vue项目中引用element-ui时 让el-input 获取焦点的方法

在制作项目的时候遇到一个需求&#xff0c;点击一个按钮弹出一个input输入框&#xff0c;并让输入框获得焦点&#xff0c;项目中引用了element-ui 在网上查找了很多方法&#xff0c;但是在实际使用中发现了一个问题无论是使用$ref获取input元素然后使用focus方法还是使用饿了么…

java excel处理框架,Java三方—-excel框架之POI的使用一

Apache POI是Apache软件基金会的开放源码函式库&#xff0c;POI提供API给Java程序对Microsoft Office格式档案读和写的功能。pdf框架之IText的使用&#xff0c;参见我的博客&#xff1a;Java三方—->pdf框架之IText的使用。今天我们开始POI中Excel部分的学习。POI框架的简单…

关于background-*的一些属性

1、盒模型 盒模型从外到内一次为&#xff1a;margin-box、border-box、padding-box、content-box。 2、一些属性设置的相对位置 ⑴background-position的属性值&#xff08;top/right/bottom/left/center&#xff09;起始位置是相对于padding-box外边沿开始的&#xff0c;…

设计模式:不可变的嵌入式构建器

上周&#xff0c;我写了关于什么使图案成为反图案。 本周&#xff0c;我提出一种设计模式…或等待……也许这是一种反模式。 还是&#xff1f; 让我们看看&#xff01; 当有一个类可以构建另一个实例时&#xff0c;构建器模式是一种编程样式。 构建器模式的最初目的是将对象的…

Outlook邮件的右键菜单中添加自定义按钮

customUI代码如下&#xff1a; <customUI xmlns"http://schemas.microsoft.com/office/2009/07/customui"><contextMenus><contextMenu idMso"ContextMenuMailItem"> <button id"button1" label"修改件名"…

vue 项目的I18n国际化之路

I18n (internationalization ) ---未完善 产品国际化是产品后期维护及推广中重要的一环&#xff0c;通过国际化操作使得产品能更好适应不同语言和地区的需求 国际化重点&#xff1a;1、 语言语言本地化2、 文化颜色、习俗等3、 书写习惯日期格式、时区、数字格式、书写方向备…

华中师范大学邮箱matlab,18春[华中师范大学]华师《Matlab基础与应用》在线作业1(100分)...

试卷总分:100 得分:100第1题,用round函数四舍五入对数组[2.48 6.39 3.93 8.52]取整&#xff0c;结果为( )。A、[2 6 3 8]B、[2 6 4 8]C、[2 6 4 9]D、[3 7 4 9 ]第2题,下列变量名中( )是合法的。A、char_1B、x*yC、x\yD、end第3题,指出下列错误的指令是( )。A、syms a b;…

nginx 篇

nginx 安装 下载必要组件 nginx下载地址 http://nginx.org/en/download.htmlpcre库下载地址&#xff0c;nginx需要 http://sourceforge.net/projects/pcre/files/pcre/zlib下载地址&#xff0c;nginx需要 http://www.zlib.net/openssl下载地址&#xff0c;nginx需要 https://gi…

使用IAM保护您的AWS基础架构

在开发新产品并发现合适的产品市场时&#xff0c;每个团队都需要快速行动。 尤其是初创公司&#xff0c;因为公司的整个未来都取决于快速找到为您的产品付款的人。 对于初创企业和其他团队来说&#xff0c; Amazon Web Services是令人难以置信的工具&#xff0c;可以快速构建其…

Linux命令集锦:tmux命令

tmux是一款优秀的终端复用软件&#xff0c;平时用到的强大功能有下面两个&#xff1a; 窗口管理&#xff1a;同时启用多个窗口&#xff1b; 保护现场&#xff1a;连接到远程主机之后&#xff0c;一旦断开&#xff0c;那么当前账户登录的任务就被取消了&#xff0c;但是使用 tmu…