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交互的方式。
翻译自: https://www.javacodegeeks.com/2014/02/java-8-friday-goodies-lambdas-and-sorting.html
Java 8 Friday Goodies:Lambda和排序相关推荐
- q7goodies事例_Java 8 Friday Goodies:Lambda和排序
q7goodies事例 在Data Geekery ,我们喜欢Java. 而且,由于我们真的很喜欢jOOQ的流畅的API和查询DSL ,我们对Java 8将为我们的生态系统带来什么感到非常兴奋. 我们 ...
- Java 8 Friday Goodies:Lambda和SQL
在 Data Geekery ,我们喜欢Java. 而且,由于我们真的很喜欢 jOOQ的流畅的API和查询DSL ,我们对Java 8将为我们的生态系统带来什么感到非常兴奋. 我们已经 写了一些关于J ...
- Java 8 Friday Goodies:Lambda和XML
在Data Geekery ,我们喜欢Java. 而且,由于我们真的很喜欢jOOQ的流畅的API和查询DSL ,我们对Java 8将为我们的生态系统带来什么感到非常兴奋. 我们已经写了一些关于Java ...
- 使用NetBeans Lambda支持在Java 8中使用Lambda表达式对列表进行排序
作为JSR 335的一部分, Lambda表达式已从Java 8开始引入Java语言,这是Java语言的一个重大变化. 如果您想了解更多关于Lambda表达式以及JSR 335的信息,可以访问以下资源 ...
- java8 lambda map排序_Android兼容Java 8语法特性的原理分析
本文主要阐述了Lambda表达式及其底层实现(invokedynamic指令)的原理.Android第三方插件RetroLambda对其的支持过程.Android官方最新的dex编译器D8对其的编译支 ...
- Java 8 Friday Goodies:新的新I / O API
在Data Geekery ,我们喜欢Java. 而且,由于我们真的很喜欢jOOQ的流畅的API和查询DSL ,我们对Java 8将为我们的生态系统带来什么感到非常兴奋. 我们已经写了一些关于Java ...
- Java 8 Friday Goodies:SQL ResultSet流
在Data Geekery ,我们喜欢Java. 而且,由于我们真的很喜欢jOOQ的流畅的API和查询DSL ,我们对Java 8将为我们的生态系统带来什么感到非常兴奋. 我们已经写了一些关于Java ...
- Java 8 Friday Goodies:本地交易范围
在Data Geekery ,我们喜欢Java. 而且,由于我们真的很喜欢jOOQ的流畅的API和查询DSL ,我们对Java 8将为我们的生态系统带来什么感到非常兴奋. 我们已经写了一些关于Java ...
- Java 8 Friday Goodies:轻松派本地缓存
在Data Geekery ,我们喜欢Java. 而且,由于我们真的很喜欢jOOQ的流畅的API和查询DSL ,我们对Java 8将为我们的生态系统带来什么感到非常兴奋. 我们已经写了一些关于Java ...
最新文章
- The Innovation | Volume 2 Issue 4 正式出版
- 100年前没人信他,但他仅1项研究便远程摧毁万架飞机……
- Teradata join 优化
- 用法 the_【课堂】a、an、the的用法
- 第7章:项目成本管理习题总结
- 再看数据库——(2)视图
- java面向对象程序设计编程题,已拿到offer
- sql主键_SQL主键
- pycharm显示全部数据_必备 | 提升效率的数据分析工具,吴恩达都在用
- 微信小程序 - 文本框显示限制最大长度
- 小程序 | 微信小程序布局左对齐自动换行
- Windows10更新错误显示0x8000ffff,易升更新0xc1900107
- win10 appdata文件夹在哪 隐藏文件夹appdata的打开方法
- Python使用免费天气API,获取全球任意地区的天气情况
- 2022年全球20大国际航运中心榜单公布,上海蝉联第三,与新加坡伦敦差距缩小 | 美通社头条...
- 流体机械原理及设计08
- Ardupilot 绕圈模式分析
- Proxmark3的编译
- python PEP8问题及解决
- 技术、产业、人才三管齐下,数字人民币渐行渐近 | 产业区块链发展周报
热门文章
- springboot创建项目
- java把控件跑挂了_Java代码动态修改 ConstraintLayout 内控件布局的辅助类
- run spark pi_Spark Run本地设计模式
- java流写入数据库_使用Java流查询数据库
- 海域动态监视监测管理系统_监视和管理备份系统
- 春天猫rtsy_春天重试,因为冬天来了
- kie-api_7.0上的新KIE持久性API
- 琥珀ai_琥珀项目:Java的未来暴露
- hystrix熔断 简介_Hystrix简介– Hello World
- sap界面功能_功能介面