Java基础教程(17)-Java8中的lambda表达式和Stream、Optional

举报
厨师之乡 发表于 2024/04/26 07:13:21 2024/04/26
【摘要】 lambda表达式把支持函数式编程的编码风格称为Lambda表达式。Lambda 表达式,也可称为闭包, 函数式编程函数是一种最基本的任务,一个大型程序就是一个顶层函数调用若干底层函数,这些被调用的函数又可以调用其他函数,即大任务被一层层拆解并执行。所以函数就是面向过程的程序设计的基本单元。Java不支持单独定义函数,但可以把静态方法视为独立的函数,把实例方法视为自带 this 参数的函数...

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(终止操作): 终止操作用于返回我们最终需要的数据,只能有一个终止操作
中间操作
  1. filter: 过滤流中的某些元素

  2. distinct: 通过流中元素的 hashCode() 和 equals() 去除重复元素

  3. 排序
    sorted():返回由此流的元素组成的流,根据自然顺序排序。
    sorted(Comparator com):返回由该流的元素组成的流,根据提供的 Comparator进行排序。

  4. 截取
    limit(n):返回由此流的元素组成的流,截短长度不能超过 n
    skip(n):在丢弃流的第n元素后,配合limit(n)可实现分页

  5. 转换
    map:接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
    flatMap:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。

  6. 消费
    peek:如同于map,能得到流中的每一个元素。但map接收的是一个Function表达式,有返回值;而peek接收的是Consumer表达式,没有返回值。

终止操作
  1. 循环:forEach

  2. 计算:min、max、count、sum
    min:返回流中元素最小值
    max:返回流中元素最大值
    count:返回流中元素的总个数
    sum:求和

  3. 匹配:anyMatch、 allMatch、 noneMatch、 findFirst、 findAny
    anyMatch:接收一个 Predicate 函数,只要流中有一个元素满足该断言则返回true,否则返回false
    allMatch:接收一个 Predicate 函数,当流中每个元素都符合该断言时才返回true,否则返回false
    noneMatch:接收一个 Predicate 函数,当流中每个元素都不符合该断言时才返回true,否则返回false
    findFirst:返回流中第一个元素
    findAny:返回流中的任意元素

  4. 收集器: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<T, U> mapper):如果optional不为空,则将optional中的对象 t 映射成另外一个对象 u,并将 u 存放到一个新的optional容器中。

  • flatMap(Function<T,Optional > mapper):跟上面一样,在optional不为空的情况下,将对象t映射成另外一个optional

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。