首页 > 编程语言 >读Java实战(第二版)笔记02_行为参数化Lambda表达式

读Java实战(第二版)笔记02_行为参数化Lambda表达式

时间:2023-02-06 07:55:05浏览次数:46  
标签:02 Java 函数 2.7 接口 2.1 方法 Lambda

1. 行为参数化

1.1. 处理频繁变更的需求的一种软件开发模式

1.1.1. 不管你做什么,用户的需求肯定会变

1.1.2. 可让代码更好地适应不断变化的要求,减轻未来的工作量

1.2. 一个方法接受多个不同的行为作为参数,并在内部使用它们,完成不同行为的能力

1.2.1. 类似于在内联“传递代码”

1.2.2. 重复使用同一个方法,给它不同的行为来达到不同的目的

1.2.2.1. DRY(Don't Repeat Yourself,不要重复自己)

1.2.2.2. 例如:把迭代要筛选的集合的逻辑与对集合中每个元素应用的行为区分开来

1.3. 传递代码就是将新行为作为参数传递给方法

1.3.1. 在Java 8之前可以用匿名类

1.3.1.1. 匿名类和局部类(块中定义的类)差不多,但匿名类没有名字

1.3.1.2. GUI应用程序中经常使用匿名类来创建事件处理器对象

1.3.1.3. 声明很多只要实例化一次的类

1.3.2. 以用不同行为进行参数化的方法,包括排序、线程和GUI处理

2. Lambda表达式

2.1. 基本语法

2.1.1. 块-风格的Lambda

2.1.1.1. (parameters) -› { statements; }

2.1.2. 表达式-风格的Lambda

2.1.2.1. (parameters) -› expression

2.2. 没有声明名称的方法

2.3. 和匿名类一样,也能作为参数传递给一个方法

2.4. 允许你直接以内联的形式为函数式接口的抽象方法提供实现,并把整个表达式作为函数式接口的实例

2.5. 一种简洁的可传递匿名函数:它没有名称,但它有参数列表、函数主体、返回类型,可能还有一个可以抛出的异常列表

2.5.1. 匿名

2.5.2. 函数

2.5.2.1. 有参数列表、函数主体、返回类型,还可能有可以抛出的异常列表

2.5.3. 传递

2.5.3.1. 可以作为参数传递给方法或存储在变量中

2.5.4. 简洁

2.5.4.1. 无须像匿名类那样写很多模板代码

2.6. 方法调用的返回值为空时,Java语言规范有一条特殊的规定,不需要使用括号环绕返回值为空的单行方法调用

2.7. 捕获Lambda允许使用自由变量(不是参数,而是在外层作用域中定义的变量),就像匿名类一样

2.7.1. 可以没有限制地捕获(也就是在其主体中引用)实例变量和静态变量

2.7.2. 局部变量必须显式声明为final,或事实上是final

2.7.2.1. 只能捕获指派给它们的局部变量一次

2.7.2.2. 捕获实例变量可以被看作捕获最终局部变量this

2.7.2.3. 不能修改定义Lambda的方法的局部变量的内容。这些变量必须是隐式最终的

2.7.3. 实例变量都存储在堆中

2.7.3.1. 堆是在线程之间共享的

2.7.4. 局部变量则保存在栈上

2.7.4.1. 允许捕获可改变的局部变量,就会引发造成线程不安全的新的可能性

2.7.4.2. 在访问自由局部变量时,实际上是在访问它的副本,而不是访问基本变量

2.7.5. 不鼓励你使用改变外部变量的典型命令式编程模式

2.8. Lambda是对值封闭,而不是对变量封闭

2.9. 闭包就是一个函数的实例,且它可以无限制地访问那个函数的非本地变量

2.9.1. 可以访问和修改其作用域之外的变量

3. 匿名内部类

3.1. 也可以完成Lambda表达式同样的事情,比较笨拙:需要提供一个实现,然后再直接内联将它实例化

4. 方法引用

4.1. 仅调用特定方法的Lambda的一种快捷写法

4.1.1. 更易读

4.1.2. 更自然

4.2. 仅涉及单一方法的Lambda的语法糖

4.2.1. 同样的事情时要写的代码更少

4.3. 如果一个Lambda代表的只是“直接调用这个方法”,那最好还是用名称来调用它,而不是去描述如何调用它

4.4. 指向静态方法的方法引用

4.4.1. 例如Integer的parseInt方法,写作Integer::parseInt

4.5. 指向任意类型实例方法的方法引用

4.5.1. 例如String的length方法,写作String::length

4.6. 指向现存对象或表达式实例方法的方法引用

4.6.1. 例如你有一个局部变量expensive Transaction保存了Transaction类型的对象,它提供了实例方法getValue,那你就可以这么写expensive-Transaction::getValue

4.7. 构造函数引用

4.7.1. 对于一个现有构造函数,你可以利用它的名称和关键字new来创建它的一个引用:ClassName::new

4.7.2. 不将构造函数实例化却能够引用它

4.7.3. 语言本身并没有提供的函数式接口,可以自己创建一个

5. 函数式接口

5.1. 只定义一个抽象方法的接口

5.1.1. 很多默认方法,只要接口只定义了一个抽象方法,仍然是一个函数式接口

5.1.2. 默认方法不是抽象方法

5.2. 函数式接口的抽象方法的签名称为函数描述符

5.2.1. 基本上就是Lambda表达式的签名

5.3. @FunctionalInterface

5.3.1. 这个标注用于表示该接口会设计成一个函数式接口,因此对文档来说非常有用

5.3.2. 不是必需的,但对于为此设计的接口而言,使用它是比较好的做法

5.4. java.util.function包中新的函数式接口

5.4.1. Predicate‹T›接口定义了一个名叫test的抽象方法,它接受泛型T对象,并返回一个boolean

5.4.1.1. 谓词(即一个返回boolean值的函数)

5.4.2. Consumer‹T›接口定义了一个名叫accept的抽象方法,它接受泛型T的对象,没有返回(void)

5.4.3. Function‹T, R›接口定义了一个叫作apply的抽象方法,它接受泛型T的对象,并返回一个泛型R的对象

5.4.3.1. 配了andThen和compose两个默认方法,它们都会返回Function的一个实例

5.4.4. Supplier‹T›

5.4.5. BinaryOperator‹T›

5.5. 函数式接口中的任何一个都不允许抛出受检异常(checked exception)

5.5.1. 定义一个自己的函数式接口,并声明受检异常

5.5.2. 把Lambda包在一个try/catch块中

5.5.2.1. 环绕执行(execute around)模式

6. 装箱(boxing)

6.1. 将基本类型转换为对应的引用类型的机制

7. 拆箱(unboxing)

7.1. 将引用类型转换为对应的基本类型

8. 自动装箱机制

8.1. 装箱和拆箱操作是自动完成的

9. 特殊处理

9.1. IntPredicate

9.2. DoublePredicate

9.3. ToIntFunction‹T›

9.4. IntConsumer

9.5. LongBinaryOperator

9.6. IntFunction

9.7. IntToDoubleFunction

10. 目标类型

10.1. Lambda的类型是从使用Lambda的上下文推断出来的

10.2. 上下文(比如,接受它传递的方法的参数,或接受它的值的局部变量)中Lambda表达式需要的类型

10.3. 同一个Lambda表达式就可以与不同的函数式接口联系起来,只要它们的抽象方法签名能够兼容

10.4. Lambda表达式的上下文是Object(目标类型)。但Object不是一个函数式接口。

10.4.1. 你可以把目标类型改成Runnable,它的函数描述符是() -› void

10.5. 为了消除显式的二义性,你可以对Lamda进行强制类型转换

10.6. 有时候显式写出类型更易读,有时候去掉它们更易读

标签:02,Java,函数,2.7,接口,2.1,方法,Lambda
From: https://www.cnblogs.com/lying7/p/17094341.html

相关文章

  • VS2022 MFC OpenCV环境搭建
    无法打开opencv2/opencv.hpp文件错误:在项目属性,配置属性,VC++目录:可执行目录: C:\opencv\build\x64\vc15\bin包含目录:C:\opencv\build\includeC:\opencv\build\i......
  • 有序数组的平方-力扣(Java)
    977.有序数组的平方题目描述给你一个按非递减顺序排序的整数数组nums,返回每个数字的平方组成的新数组,要求也按非递减顺序排序。思路我采用的是双指针进行解答......
  • 洛谷oj题单【入门2】分支结构-入门难度(Java)
    洛谷oj题单【入门2】分支结构-入门难度(Java)来源:https://www.luogu.com.cn/training/101#problemsP5709【深基2.习6】ApplesPrologue/苹果和虫子importjava.util.Sc......
  • 代码随想录算法训练营第五天【哈希表】242.有效的字母异位词、349.两个数组的交集、20
    242.有效的字母异位词力扣题目链接: 349.两个数组的交集力扣题目链接: 202.快乐数力扣题目链接: 1.两数之和力扣题目链接:......
  • x210-2023-02-05
    1、QT4.8运行不起来,但是android4.0.4能运行起来,出错的提示在下图5.550698起始的地方,这是由于很久之前的一次烧录设置了bootcmd相关内容时不小心把bootargs的内容给删除了,但......
  • 2023.2.5
    Generic(泛型)用泛型来指定集合中存储的数据类型使用泛型的好处1.集合中存储的元素类型统一了2.从集合中取出的元素类型是泛型指定的类型,不用更多的向下转型泛型的......
  • day02-REST和SpringMVC映射请求数据
    REST和SpringMVC映射请求数据7.REST-优雅的url请求风格7.1REST基本介绍REST风格详细介绍REST:即RepresentationalStateTransfer,表述性状态传递。它结构清晰,同时......
  • 技术规划与产品路标开发实践(2023.2.17~18,深圳)
    【课程背景】技术规划流程TPP(TechnologyPlanningProcess),就是根据业务和市场目标进行所需技术的识别和分析,并给出相应的策略的过程。技术规划的根本目标是让产品在市场竞......
  • JavaScript 基础知识(四)
    前面已经介绍HTML和CSS,这两个是网页结构和样式,而负责控制网页行为的是javascript。浏览器上直接可以解释执行,而独立运行就需要nodejs集成运行环境。01-JavaScript的基......
  • XMReport 支持通过前端JavaScript生成PDF打印报表
    XMReport支持通过前端JavaScript生成PDF打印报表Hello大家好,XMReport现在新增了通过JavaScript纯前端生成PDF打印报表的特性:1.整个引擎在浏览器端通过JavaScript运行......