首页 Java java教程 解析Java 8 Optional类实例教程

解析Java 8 Optional类实例教程

May 24, 2017 am 11:47 AM

        身为一名Java程序员,大家可能都有这样的经历:调用一个方法得到了返回值却不能直接将返回值作为参数去调用别的方法。我们首先要判断这个返回值是否为null,只有在非空的前提下才能将其作为其他方法的参数。这正是一些类似Guava的外部API试图解决的问题。一些JVM编程语言比如Scala、Ceylon等已经将对在核心API中解决了这个问题。在我的前一篇文章中,介绍了Scala是如何解决了这个问题。

新版本的Java,比如Java 8引入了一个新的Optional类。Optional类的Javadoc描述如下:

这是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。
登录后复制
本文会逐个探讨Optional类包含的方法,并通过一两个示例展示如何使用。

of

为非null的值创建一个Optional。
登录后复制
of方法通过工厂方法创建Optional类。需要注意的是,创建对象时传入的参数不能为null。如果传入参数为null,则抛出NullPointerException 。

1

2

3

4


//调用工厂方法创建Optional实例

Optional<<a href="http://www.php.cn/wiki/57.html" target="_blank">String</a>> name = Optional.of("Sanaulla");

//传入参数为null,抛出NullPointerException.

Optional<String> someNull = Optional.of(null);


ofNullable

为指定的值创建一个Optional,如果指定的值为null,则返回一个空的Optional。

ofNullable与of方法相似,唯一的区别是可以接受参数为null的情况。示例如下:

1

2

3


//下面创建了一个不包含任何值的Optional实例

//例如,值为&#39;null&#39;

Optional empty = Optional.ofNullable(null);


isPresent

非常容易理解

如果值存在返回true,否则返回false。

类似下面的代码:

1

2

3

4

5


//isPresent方法用来检查Optional实例中是否包含值

if(name.isPresent()) {

//在Optional实例内调用get()返回已存在的值

System.out.<a href="http://www.php.cn/wiki/1362.html" target="_blank">print</a>ln(name.get());//输出Sanaulla

}


get

如果Optional有值则将其返回,否则抛出NoSuchElementException。

上面的示例中,get方法用来得到Optional实例中的值。下面我们看一个抛出NoSuchElementException的例子:

1

2

3

4

5

6

7


//执行下面的代码会输出:No value present

try{

//在空的Optional实例上调用get(),抛出NoSuchElementException

System.out.println(empty.get());

}catch(NoSuchElementException ex) {

System.out.println(ex.getMessage());

}


ifPresent

如果Optional实例有值则为其调用consumer,否则不做处理

要理解ifPresent方法,首先需要了解Consumer类。简答地说,Consumer类包含一个抽象方法。该抽象方法对传入的值进行处理,但没有返回值。Java8支持不用接口直接通过lambda表达式传入参数。

如果Optional实例有值,调用ifPresent()可以接受接口段或lambda表达式。类似下面的代码:

1

2

3

4

5


//ifPresent方法接受lambda表达式作为参数。

//lambda表达式对Optional的值调用consumer进行处理。

name.ifPresent((value) -> {

System.out.println("The length of the value is: " + value.length());

});


orElse

如果有值则将其返回,否则返回指定的其它值。

如果Optional实例有值则将其返回,否则返回orElse方法传入的参数。示例如下:

1

2

3

4

5

6


//如果值不为null,orElse方法返回Optional实例的值。

//如果为null,返回传入的消息。

//输出:There is no value present!

System.out.println(empty.orElse("There is no value present!"));

//输出:Sanaulla

System.out.println(name.orElse("There is some value!"));

orElseGet

orElseGet与orElse方法类似,区别在于得到的默认值。orElse方法将传入的字符串作为默认值,orElseGet方法可以接受Supplier接口的实现用来生成默认值。示例如下:

1

2

3

4

5

6


//orElseGet与orElse方法类似,区别在于orElse传入的是默认值,

//orElseGet可以接受一个lambda表达式生成默认值。

//输出:Default Value

System.out.println(empty.orElseGet(() -> "Default Value"));

//输出:Sanaulla

System.out.println(name.orElseGet(() -> "Default Value"));


orElseThrow

如果有值则将其返回,否则抛出supplier接口创建的异常。

在orElseGet方法中,我们传入一个Supplier接口。然而,在orElseThrow中我们可以传入一个lambda表达式或方法,如果值不存在来抛出异常。示例如下:

1

2

3

4

5

6

7

8

9


try{

//orElseThrow与orElse方法类似。与返回默认值不同,

//orElseThrow会抛出lambda表达式或方法生成的异常

empty.orElseThrow(ValueAbsentException::new);

}catch(Throwable ex) {

//输出: No value present in the Optional instance

System.out.println(ex.getMessage());

}


ValueAbsentException定义如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15


<a href="http://www.php.cn/wiki/164.html" target="_blank">class</a>ValueAbsentException <a href="http://www.php.cn/wiki/166.html" target="_blank">extends</a>Throwable {

publicValueAbsentException() {

<a href="http://www.php.cn/code/8202.html" target="_blank">super</a>();

}

publicValueAbsentException(String msg) {

super(msg);

}

@Override

publicString getMessage() {

<a href="http://www.php.cn/wiki/135.html" target="_blank">return</a>"No value present in the Optional instance";

}

}


map

map方法文档说明如下:

如果有值,则对其执行调用mapping函数得到返回值。如果返回值不为null,则创建包含mapping返回值的Optional作为map方法返回值,否则返回空Optional。

map方法用来对Optional实例的值执行一系列操作。通过一组实现了Function接口的lambda表达式传入操作。如果你不熟悉Function接口,可以参考我的这篇博客。map方法示例如下:

1

2

3

4


//map方法执行传入的lambda表达式参数对Optional实例的值进行修改。

//为lambda表达式的返回值创建新的Optional实例作为map方法的返回值。

Optional<String> upperName = name.map((value) -> value.toUpperCase());

System.out.println(upperName.orElse("No value found"));


flatMap

如果有值,为其执行mapping函数返回Optional类型返回值,否则返回空Optional。flatMap与map(Funtion)方法类似,区别在于flatMap中的mapper返回值必须是Optional。调用结束时,flatMap不会对结果用Optional封装。

flatMap方法与map方法类似,区别在于mapping函数的返回值不同。map方法的mapping函数返回值可以是任何类型T,而flatMap方法的mapping函数必须是Optional。

参照map函数,使用flatMap重写的示例如下:

1

2

3

4

5


//flatMap与map(Function)非常类似,区别在于传入方法的lambda表达式的返回类型。

//map方法中的lambda表达式返回值可以是任意类型,在map函数返回之前会包装为Optional。

//但flatMap方法中的lambda表达式返回值必须是Optionl实例。

upperName = name.flatMap((value) -> Optional.of(value.toUpperCase()));

System.out.println(upperName.orElse("No value found"));//输出SANAULLA


filter

filter个方法通过传入限定条件对Optional实例的值进行过滤。文档描述如下:

如果有值并且满足断言条件返回包含该值的Optional,否则返回空Optional。

读到这里,可能你已经知道如何为filter方法传入一段代码。是的,这里可以传入一个lambda表达式。对于filter函数我们应该传入实现了Predicate接口的lambda表达式。如果你不熟悉Predicate接口,可以参考这篇文章。

现在我来看看filter的各种用法,下面的示例介绍了满足限定条件和不满足两种情况:

1

2

3

4

5

6

7

8

9

10


//filter方法检查给定的Option值是否满足某些条件。

//如果满足则返回同一个Option实例,否则返回空Optional。

Optional<String> longName = name.filter((value) -> value.length() > 6);

System.out.println(longName.orElse("The name is less than 6 characters"));//输出Sanaulla

//另一个例子是Optional值不满足filter指定的条件。

Optional<String> anotherName = Optional.of("Sana");

Optional<String> shortName = anotherName.filter((value) -> value.length() > 6);

//输出:name长度不足6字符

System.out.println(shortName.orElse("The name is less than 6 characters"));

以上,我们介绍了Optional类的各个方法。下面通过一个完整的示例对用法集中展示:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69


publicclass OptionalDemo {

publicstatic void <a href="http://www.php.cn/wiki/646.html" target="_blank">main</a>(String[] args) {

//创建Optional实例,也可以通过方法返回值得到。

Optional<String> name = Optional.of("Sanaulla");

//创建没有值的Optional实例,例如值为&#39;null&#39;

Optional empty = Optional.ofNullable(null);

//isPresent方法用来检查Optional实例是否有值。

if(name.isPresent()) {

//调用get()返回Optional值。

System.out.println(name.get());

}

try{

//在Optional实例上调用get()抛出NoSuchElementException。

System.out.println(empty.get());

}catch(NoSuchElementException ex) {

System.out.println(ex.getMessage());

}

//ifPresent方法接受lambda表达式参数。

//如果Optional值不为空,lambda表达式会处理并在其上执行操作。

name.ifPresent((value) -> {

System.out.println("The length of the value is: " + value.length());

});

//如果有值orElse方法会返回Optional实例,否则返回传入的<a href="http://www.php.cn/php/php-tp-errormessage.html" target="_blank">错误信息</a>。

System.out.println(empty.orElse("There is no value present!"));

System.out.println(name.orElse("There is some value!"));

//orElseGet与orElse类似,区别在于传入的默认值。

//orElseGet接受lambda表达式生成默认值。

System.out.println(empty.orElseGet(() -> "Default Value"));

System.out.println(name.orElseGet(() -> "Default Value"));

try{

//orElseThrow与orElse方法类似,区别在于返回值。

//orElseThrow抛出由传入的lambda表达式/方法生成异常。

empty.orElseThrow(ValueAbsentException::new);

}catch(Throwable ex) {

System.out.println(ex.getMessage());

}

//map方法通过传入的lambda表达式修改Optonal实例默认值。

//lambda表达式返回值会包装为Optional实例。

Optional<String> upperName = name.map((value) -> value.toUpperCase());

System.out.println(upperName.orElse("No value found"));

//flatMap与map(Funtion)非常相似,区别在于lambda表达式的返回值。

//map方法的lambda表达式返回值可以是任何类型,但是返回值会包装成Optional实例。

//但是flatMap方法的lambda返回值总是Optional类型。

upperName = name.flatMap((value) -> Optional.of(value.toUpperCase()));

System.out.println(upperName.orElse("No value found"));

//filter方法检查Optiona值是否满足给定条件。

//如果满足返回Optional实例值,否则返回空Optional。

Optional<String> longName = name.filter((value) -> value.length() > 6);

System.out.println(longName.orElse("The name is less than 6 characters"));

//另一个示例,Optional值不满足给定条件。

Optional<String> anotherName = Optional.of("Sana");

Optional<String> shortName = anotherName.filter((value) -> value.length() > 6);

System.out.println(shortName.orElse("The name is less than 6 characters"));

}

}


上述代码输出如下:

Sanaulla
No
 value present
The
 length of the value is: 8
There
 is no value present!
Sanaulla
Default
 Value
Sanaulla
No
 value present inthe Optional instance
SANAULLA
SANAULLA
Sanaulla
The
 name is lessthan 6 characters
登录后复制

【相关推荐】

 1. Java 8新增的API--Optional 的使用实例

 2. 分享Java8中新引入的类Optional实例代码

以上是解析Java 8 Optional类实例教程的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您听不到任何人,如何修复音频
4 周前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它们
4 周前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

Java 中的完美数 Java 中的完美数 Aug 30, 2024 pm 04:28 PM

Java 完美数指南。这里我们讨论定义,如何在 Java 中检查完美数?,示例和代码实现。

Java 中的随机数生成器 Java 中的随机数生成器 Aug 30, 2024 pm 04:27 PM

Java 随机数生成器指南。在这里,我们通过示例讨论 Java 中的函数,并通过示例讨论两个不同的生成器。

Java中的Weka Java中的Weka Aug 30, 2024 pm 04:28 PM

Java 版 Weka 指南。这里我们通过示例讨论简介、如何使用weka java、平台类型和优点。

Java 中的史密斯数 Java 中的史密斯数 Aug 30, 2024 pm 04:28 PM

Java 史密斯数指南。这里我们讨论定义,如何在Java中检查史密斯号?带有代码实现的示例。

Java Spring 面试题 Java Spring 面试题 Aug 30, 2024 pm 04:29 PM

在本文中,我们保留了最常被问到的 Java Spring 面试问题及其详细答案。这样你就可以顺利通过面试。

突破或从Java 8流返回? 突破或从Java 8流返回? Feb 07, 2025 pm 12:09 PM

Java 8引入了Stream API,提供了一种强大且表达力丰富的处理数据集合的方式。然而,使用Stream时,一个常见问题是:如何从forEach操作中中断或返回? 传统循环允许提前中断或返回,但Stream的forEach方法并不直接支持这种方式。本文将解释原因,并探讨在Stream处理系统中实现提前终止的替代方法。 延伸阅读: Java Stream API改进 理解Stream forEach forEach方法是一个终端操作,它对Stream中的每个元素执行一个操作。它的设计意图是处

Java 中的时间戳至今 Java 中的时间戳至今 Aug 30, 2024 pm 04:28 PM

Java 中的时间戳到日期指南。这里我们还结合示例讨论了介绍以及如何在java中将时间戳转换为日期。

Java程序查找胶囊的体积 Java程序查找胶囊的体积 Feb 07, 2025 am 11:37 AM

胶囊是一种三维几何图形,由一个圆柱体和两端各一个半球体组成。胶囊的体积可以通过将圆柱体的体积和两端半球体的体积相加来计算。本教程将讨论如何使用不同的方法在Java中计算给定胶囊的体积。 胶囊体积公式 胶囊体积的公式如下: 胶囊体积 = 圆柱体体积 两个半球体体积 其中, r: 半球体的半径。 h: 圆柱体的高度(不包括半球体)。 例子 1 输入 半径 = 5 单位 高度 = 10 单位 输出 体积 = 1570.8 立方单位 解释 使用公式计算体积: 体积 = π × r2 × h (4

See all articles