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

简介: 【4月更文挑战第17天】Lambda表达式是Java 8引入的函数式编程特性,允许函数作为参数或返回值。它有简洁的语法:`(parameters) -> expression 或 (parameters) ->{ statements; }`。FunctionalInterface注解用于标记单方法接口,可以用Lambda替换。

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表达式,没有返回值。
    终止操作
  7. 循环:forEach

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

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

  10. 收集器: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

相关文章
|
17天前
|
Java
探索Java中的Lambda表达式
【10月更文挑战第37天】本文将带你深入理解Java的Lambda表达式,从基础语法到高级特性,通过实例讲解其在函数式编程中的应用。我们还将探讨Lambda表达式如何简化代码、提高开发效率,并讨论其在实际项目中的应用。
|
20天前
|
Java API
Java中的Lambda表达式与函数式编程####
【10月更文挑战第29天】 本文将深入探讨Java中Lambda表达式的实现及其在函数式编程中的应用。通过对比传统方法,我们将揭示Lambda如何简化代码、提高可读性和维护性。文章还将展示一些实际案例,帮助读者更好地理解和应用Lambda表达式。 ####
|
22天前
|
Java 大数据 API
14天Java基础学习——第1天:Java入门和环境搭建
本文介绍了Java的基础知识,包括Java的简介、历史和应用领域。详细讲解了如何安装JDK并配置环境变量,以及如何使用IntelliJ IDEA创建和运行Java项目。通过示例代码“HelloWorld.java”,展示了从编写到运行的全过程。适合初学者快速入门Java编程。
|
24天前
|
Java API 开发者
Java中的Lambda表达式与函数式编程####
在Java的演变过程中,Lambda表达式和函数式编程的引入无疑是一次重大的飞跃。本文将深入探讨Lambda表达式的定义、用法及优势,并结合实例说明如何在Java中利用Lambda表达式进行函数式编程。通过对比传统编程方式,揭示Lambda表达式如何简化代码、提高开发效率和可维护性。 ####
|
26天前
|
安全 Java 编译器
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
|
26天前
|
Java 开发工具 Android开发
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
|
26天前
|
Java 编译器 Android开发
Kotlin教程笔记(28) -Kotlin 与 Java 混编
Kotlin教程笔记(28) -Kotlin 与 Java 混编
|
4天前
|
安全 Java API
Java中的Lambda表达式与Stream API的高效结合####
探索Java编程中Lambda表达式与Stream API如何携手并进,提升数据处理效率,实现代码简洁性与功能性的双重飞跃。 ####
17 0
|
1月前
|
Java API 数据处理
探索Java中的Lambda表达式与Stream API
【10月更文挑战第22天】 在Java编程中,Lambda表达式和Stream API是两个强大的功能,它们极大地简化了代码的编写和提高了开发效率。本文将深入探讨这两个概念的基本用法、优势以及在实际项目中的应用案例,帮助读者更好地理解和运用这些现代Java特性。
|
12天前
|
Java 编译器 Android开发
Kotlin教程笔记(28) -Kotlin 与 Java 混编
Kotlin教程笔记(28) -Kotlin 与 Java 混编
10 0