lambda表达式
把支持函数式编程的编码风格称为Lambda表达式。
Lambda 表达式,也可称为闭包,
函数式编程
函数是一种最基本的任务,一个大型程序就是一个顶层函数调用若干底层函数,这些被调用的函数又可以调用其他函数,即大任务被一层层拆解并执行。所以函数就是面向过程的程序设计的基本单元。
Java不支持单独定义函数,但可以把静态方法视为独立的函数,把实例方法视为自带 this 参数的函数。
函数式编程就是一种抽象程度很高的编程范式,函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数!
Java平台从Java 8开始,支持函数式编程。
lambda 表达式的语法格式如下:
(parameters) -> expression 或 (parameters) ->{ statements; }
lambda 表达式的重要特征:
- 可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
- 可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
- 可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
- 可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值;
只定义了单方法的接口称之为 FunctionalInterface ,用注解 @FunctionalInterface 标记; 从Java 8开始,可以用Lambda表达式替换单方法接口
Stream
Java从8开始,引入了一个全新的流式API:Stream API。它位于 java.util.stream 包中。
Stream代表的是任意Java对象的序列;
Stream API的特点是:
- Stream API提供了一套新的流式处理的抽象序列;
- Stream API支持函数式编程和链式操作;
- Stream可以表示无限序列,并且大多数情况下是惰性求值的
最常用的创建方式有:
- 1、通过数组来生成 把数组变成 Stream 使用 Arrays.strem() 方法
- 2、通过集合来生成,直接调用 stream() 方法就可以;
创建 Stream 最简单的方式是直接用 Stream.of() 静态方法,传入可变参数即创建了一个能输出确定元素的 Stream;
应用在Stream流上的操作(Stream的Api),可以分成两种:
- Intermediate(中间操作): 中间操作的返回结果都是Stream,故可以多个中间操作叠加;
- Terminal(终止操作): 终止操作用于返回我们最终需要的数据,只能有一个终止操作
中间操作
- filter: 过滤流中的某些元素
- distinct: 通过流中元素的 hashCode() 和 equals() 去除重复元素
- 排序
sorted():返回由此流的元素组成的流,根据自然顺序排序。
sorted(Comparator com):返回由该流的元素组成的流,根据提供的 Comparator进行排序。 截取
limit(n):返回由此流的元素组成的流,截短长度不能超过 n
skip(n):在丢弃流的第n元素后,配合limit(n)可实现分页转换
map:接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
flatMap:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。- 消费
peek:如同于map,能得到流中的每一个元素。但map接收的是一个Function表达式,有返回值;而peek接收的是Consumer表达式,没有返回值。终止操作
循环:forEach
计算:min、max、count、sum
min:返回流中元素最小值
max:返回流中元素最大值
count:返回流中元素的总个数
sum:求和匹配:anyMatch、 allMatch、 noneMatch、 findFirst、 findAny
anyMatch:接收一个 Predicate 函数,只要流中有一个元素满足该断言则返回true,否则返回false
allMatch:接收一个 Predicate 函数,当流中每个元素都符合该断言时才返回true,否则返回false
noneMatch:接收一个 Predicate 函数,当流中每个元素都不符合该断言时才返回true,否则返回false
findFirst:返回流中第一个元素
findAny:返回流中的任意元素收集器:toArray、collect
Optional
Optional类是 Java 8 引入的一个很有趣的特性。它主要解决的问题是空指针异常(NullPointerException)
Optional 类是一个可以为null的容器对象。如果值存在则isPresent(方法会返回true,调用get()方法会返回该对象。
- Optional 是个容器:它可以保存类型T的值,或者仅仅保存null。
- Optional提供很多有用的方法,这样我们就不用显式进行空值检测。
- Optional 类的引入很好的解决空指针异常。
使用Optional对象
Optional类的实例创建有三种方式:
Optional.empty() :创建一个空的 Optional 实例。
Optional.of(T t) :创建一个 Optional 实例,当 t为null时抛出异常(NullPointerException)。
Optional.ofNullable(T t) :创建一个 Optional 实例,但当 t为null时不会抛出异常,而是返回一个空的实例。
Optional实例方法:
isPresent():判断optional是否为空,如果空则返回false,否则返回true
ifPresent(Consumer c):如果optional不为空,则将optional中的对象传给Comsumer函数
orElse(T other):如果optional不为空,则返回optional中的对象;如果为null,则返回 other 这个默认值
orElseGet(Supplier other):如果optional不为空,则返回optional中的对象;如果为null,则使用Supplier函数生成默认值other
orElseThrow(Supplier exception):如果optional不为空,则返回optional中的对象;如果为null,则抛出Supplier函数生成的异常
filter(Predicate p):filter() 接受一个 Predicate 参数,返回测试结果为 true 的值。如果测试结果为 false,会返回一个空的 Optional。
map(Function mapper):如果optional不为空,则将optional中的对象 t 映射成另外一个对象 u,并将 u 存放到一个新的optional容器中。
flatMap(Function mapper):跟上面一样,在optional不为空的情况下,将对象t映射成另外一个optional