Lambda的本质

需求1. 按照产品的重量进行升序排序

此处使用「匿名内部类」的设计,但掺杂了较多的语法噪声,引入了不必要的复杂度。

Collections.sort(repo, new Comparator() {

@Override

public int compare(Product p1, Product p2) {

return p1.getWeight().compareTo(p2.getWeight());

}

});

使用Lambda表达式,可以进一步消除语法噪声,简化设计。

Collections.sort(repo, (Product p1, Product p2) ->

p1.getWeight().compareTo(p2.getWeight()));

也就是说,Lambda其本质是「匿名内部类」的一种「语法糖」表示,存在如下3个方面的特征:

Anonymous Function:匿名的函数

Passed Around:可作为参数或返回值进行传递,甚至可以自由地存储在变量中

Concise:相对于匿名内部类的样板代码(Boilerplate),Lambda更加简洁漂亮

类型推演

借助编译器「类型推演」的能力,可以进一步简化Lambda表达式。

Collections.sort(repo, (p1, p2) ->

p1.getWeight().compareTo(p2.getWeight()));

Lambda的形式

形式1:(parameters) -> expression

Collections.sort(repo, (p1, p2) ->

p1.getWeight().compareTo(p2.getWeight()));

形式2:(parameters) -> { statements; }

Collections.sort(repo, (p1, p2) -> {

return p1.getWeight().compareTo(p2.getWeight());

});

默认方法

先看看java.util.Collections.sort的实现,其中java.util.Collections是一个典型的「工具类」。

public final class Collectins {

private Collectins() {

}

public static void sort(List extends T> l, Comparator super T> c) {

l.sort(c);

}

}

这样的设计是反OO,为此可以将其sort搬迁至List接口中去。

public interface List extends Collection {

default void sort(Comparator super E> c) {

...

}

...

}

default方法类似于C++的虚函数。从某种意义上看,default的引入使得Java又重新回到了「多重继承」的怀抱,为设计带来了更大的弹性。

为此,设计可重构为更加符合OO的风格。

repo.sort((p1, p2) -> p1.getWeight().compareTo(p2.getWeight()));

方法引用

借助Comparator.comparing的工厂方法,结合「方法引用」可进一步提高代码的可读性。

import static java.util.Comparator.comparing;

repo.sort(comparing(Product::getWeight));

方法引用其本质是具有单一方法调用的lambda表达式的「语法糖」表示。

级联方法

需求2. 按照产品的重量降序排序

repo.sort(comparing(Product::getWeight)

.reversed());

.thenComparing(Product::getCountry));

需求3. 如果重量相同,则按照出厂国的自然序排序

repo.sort(comparing(Product::getWeight)

.reversed()

.thenComparing(Product::getCountry));

深入理解Comparator

有且仅有一个抽象方法的接口,称为「函数式接口」,使用@FunctionalInterface的注解标识。函数式接口中「抽象方法」描述了Lambda表达式的「原型」。

() -> {}也是一个合法的Lambda表达式,与Runnable接口相匹配。

也就是说,一个「函数式接口」可包含如下元素:

Abstract Method:有且仅有一个抽象方法

Default Methods:0个或多个默认方法

Static Methods: 0个或多个静态方法

对照前面的列子,可洞悉Comparator设计的巧妙。

repo.sort(comparing(Product::getWeight)

.reversed());

其中,Comparator就是一个典型的函数式接口。通过「方法级联」设计了一套简单的Comparator的DSL,增强了用户的表达力。

@FunctionalInterface

public interface Comparator {

int compare(T o1, T o2);

default Comparator reversed() {

return Collections.reverseOrder(this);

}

static >

Comparator comparing(

Function super T, ? extends U> extractor) {

return (c1, c2) -> extractor.apply(c1)

.compareTo(extractor.apply(c2));

}

}

其中,Comprator.compring的实现稍微有点复杂。

comparing是一个静态工厂方法,它生产一个Comparator类型的实例;

comparing是一个高阶函数;

接受一个函数:Function super T, ? extends U> extractor

返回一个函数:Comparator

comparing是一个语法糖,结合「方法引用」的机制,极大地改善了用户接口的表达力;

java+lambda+本质_Java8 Lambda本质论相关推荐

  1. java 拉姆表达式_Java8 lambda表达式10个示例

    Java 8 lambda表达式示例 转自importNew 原文链接 例1.用lambda表达式实现Runnable 我开始使用Java 8时,首先做的就是使用lambda表达式替换匿名类,而实现R ...

  2. 精通lambda表达式:java多核编程_Java8 Lambda表达式和流操作如何让你的代码变慢5倍...

    有许许多多关于 Java 8 中流效率的讨论,但根据 Alex Zhitnitsky 的测试结果显示:坚持使用传统的 Java 编程风格--iterator 和 for-each 循环--比 Java ...

  3. java expression 用法_浅析Java 8新特性Lambda Expression

    什么是Lambda Expression 对于Lambda Expression,我的理解是,它是一个函数表达式,如下: (int x, int y) -> x - y 符号左边定义了函数的输入 ...

  4. Java 函数式编程和 lambda 表达式

    为什么要使用函数式编程 函数式编程更多时候是一种编程的思维方式,是种方法论.函数式与命令式编程的区别主要在于:函数式编程是告诉代码你要做什么,而命令式编程则是告诉代码要怎么做.说白了,函数式编程是基于 ...

  5. java lambda函数_最常用的 Java 8 中的 Lambda 函数(项目中实用笔记)

    最常用的 Java 8 中的 Lambda 函数(项目中实用笔记) 简介 Java 8 中的新特性,虽然现在都出到了Java14版本,不过在日常的开发过程中,8的版本是足够使用了,再说现在的8以上的版 ...

  6. java8 lambda 接口_Java8新特性之一:Lambda表达式

    Java8是自java5之后最重大的一次更新,它给JAVA语言带来了很多新的特性(包括编译器.类库.工具类.JVM等),其中最重要的升级是它给我们带来了Lambda表达式和Stream API. 1. ...

  7. Java 8中使用Lambda表达式的策略模式

    策略模式是" 设计模式:可重用对象的元素"书中的模式之一 . 本书所述的策略模式的意图是: 定义一系列算法,封装每个算法,并使它们可互换. 策略使算法独立于使用该算法的客户端而变化 ...

  8. 使用NetBeans Lambda支持在Java 8中使用Lambda表达式对列表进行排序

    作为JSR 335的一部分, Lambda表达式已从Java 8开始引入Java语言,这是Java语言的一个重大变化. 如果您想了解更多关于Lambda表达式以及JSR 335的信息,可以访问以下资源 ...

  9. Java 8:测试Lambda水

    Java 8大约有一年的时间了,它具有我非常期待的语言功能: Lambda Expression . 令人遗憾的是,另一个重要功能Java平台模块已延迟到Java9.但是,将lambda表达式(或闭包 ...

最新文章

  1. R语言可视化分面图、假设检验分组t检验、可视化单变量分组分面箱图(faceting bar plot)、添加误差条(error bar)、添加p值、添加抖动数据点(jitter points)
  2. 数据库事务的ACID特性及含义
  3. Android中使用running services查看service进程内存
  4. 【C++】error C2275 “XXXX” 将此类型用作表达式非法
  5. Linux iperf 网络性能测试工具
  6. 2.4 矩阵乘以矩阵定义
  7. An error was encountered while running(Domain=LaunchSerivcesError, Code=0)
  8. linux shell 编程
  9. Java程序员的日常 —— 响应式导航Demo
  10. python2.7怎么下载安装_Windows平台下python2.7如何安装Beautiful Soup
  11. 首届Ceph亚太峰会来了!内有粉丝福利
  12. 智能交通灯linux代码实现,基于Linux的智能交通灯控制器设计
  13. Win10在Dev-C++配置Npcap
  14. Android Studio连接MuMu模拟器
  15. 关于虚拟偶像的面部表情捕捉
  16. 将Jetson XavierNX的Ubuntu系统迁移至到nvme固态硬盘上
  17. 高通量测序的数据处理与分析指北(一)_network
  18. 《桃花源记》古文鉴赏
  19. linux 在线修复磁盘,linux磁盘修复相关命令
  20. 洛谷 [P1593 因子和] {快速幂+费马小定理求逆元+求解质因子} 奋斗的珂珂~

热门文章

  1. 数据交换平台有哪些功能特点
  2. python求5_Python 5 运算符
  3. mysql get global_getdata table表格数据join mysql方法
  4. media recovery oracle,Oracle非归档模式MediaRecovery错误之--ORA-26040
  5. employees mysql_「employees」mysql示例employees数据库 - seo实验室
  6. R︱高效数据操作——data.table包(实战心得、dplyr对比、key灵活用法、数据合并)
  7. R语言︱机器学习模型评价指标+(转)模型出错的四大原因及如何纠错
  8. 2018最新Web前端经典面试试题及答案
  9. 问题007:JDK版本与JRE版本不同导致java.exe执行类文件错误 java.lang.UnsupportedClassVersionError错误...
  10. cocos2d-X   CCSprite设置贴图(图片)大小