搜索
首页Javajava教程解析Java 8 Optional类实例教程

        身为一名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实例

Optional3aa9aed1a8bb272ef06b9c4b41e94585 name = Optional.of("Sanaulla");

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

Optionalf7e83be87db5cd2d9a8a0b8117b38cd4 someNull = Optional.of(null);


ofNullable

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

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

1

2

3


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

//例如,值为'null'

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方法的返回值。

Optionalf7e83be87db5cd2d9a8a0b8117b38cd4 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。

Optionalf7e83be87db5cd2d9a8a0b8117b38cd4 longName = name.filter((value) -> value.length() > 6);

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

 

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

Optionalf7e83be87db5cd2d9a8a0b8117b38cd4 anotherName = Optional.of("Sana");

Optionalf7e83be87db5cd2d9a8a0b8117b38cd4 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实例,也可以通过方法返回值得到。

    Optionalf7e83be87db5cd2d9a8a0b8117b38cd4 name = Optional.of("Sanaulla");

 

    //创建没有值的Optional实例,例如值为'null'

    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实例。

    Optionalf7e83be87db5cd2d9a8a0b8117b38cd4 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。

    Optionalf7e83be87db5cd2d9a8a0b8117b38cd4 longName = name.filter((value) -> value.length() > 6);

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

 

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

    Optionalf7e83be87db5cd2d9a8a0b8117b38cd4 anotherName = Optional.of("Sana");

    Optionalf7e83be87db5cd2d9a8a0b8117b38cd4 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
平台独立性如何使企业级的Java应用程序受益?平台独立性如何使企业级的Java应用程序受益?May 03, 2025 am 12:23 AM

Java在企业级应用中被广泛使用是因为其平台独立性。1)平台独立性通过Java虚拟机(JVM)实现,使代码可在任何支持Java的平台上运行。2)它简化了跨平台部署和开发流程,提供了更大的灵活性和扩展性。3)然而,需注意性能差异和第三方库兼容性,并采用最佳实践如使用纯Java代码和跨平台测试。

考虑到平台独立性,Java在物联网(物联网)设备的开发中扮演什么角色?考虑到平台独立性,Java在物联网(物联网)设备的开发中扮演什么角色?May 03, 2025 am 12:22 AM

JavaplaysigantroleiniotduetoitsplatFormentence.1)itallowscodeTobewrittenOnCeandrunonVariousDevices.2)Java'secosystemprovidesuseusefidesusefidesulylibrariesforiot.3)

描述一个方案,您在Java中遇到了一个特定于平台的问题以及如何解决。描述一个方案,您在Java中遇到了一个特定于平台的问题以及如何解决。May 03, 2025 am 12:21 AM

ThesolutiontohandlefilepathsacrossWindowsandLinuxinJavaistousePaths.get()fromthejava.nio.filepackage.1)UsePaths.get()withSystem.getProperty("user.dir")andtherelativepathtoconstructthefilepath.2)ConverttheresultingPathobjecttoaFileobjectifne

Java平台独立对开发人员有什么好处?Java平台独立对开发人员有什么好处?May 03, 2025 am 12:15 AM

Java'splatFormIndenceistificantBecapeitAllowSitallowsDevelostWriTecoDeonCeandRunitonAnyPlatFormwithAjvm.this“ writeonce,runanywhere”(era)橱柜橱柜:1)交叉plat formcomplibility cross-platformcombiblesible,enablingDeploymentMentMentMentMentAcrAptAprospOspOspOssCrossDifferentoSswithOssuse; 2)

将Java用于需要在不同服务器上运行的Web应用程序的优点是什么?将Java用于需要在不同服务器上运行的Web应用程序的优点是什么?May 03, 2025 am 12:13 AM

Java适合开发跨服务器web应用。1)Java的“一次编写,到处运行”哲学使其代码可在任何支持JVM的平台上运行。2)Java拥有丰富的生态系统,包括Spring和Hibernate等工具,简化开发过程。3)Java在性能和安全性方面表现出色,提供高效的内存管理和强大的安全保障。

JVM如何促进Java的'写作一次,在任何地方运行”(WORA)功能?JVM如何促进Java的'写作一次,在任何地方运行”(WORA)功能?May 02, 2025 am 12:25 AM

JVM通过字节码解释、平台无关的API和动态类加载实现Java的WORA特性:1.字节码被解释为机器码,确保跨平台运行;2.标准API抽象操作系统差异;3.类在运行时动态加载,保证一致性。

Java的较新版本如何解决平台特定问题?Java的较新版本如何解决平台特定问题?May 02, 2025 am 12:18 AM

Java的最新版本通过JVM优化、标准库改进和第三方库支持有效解决平台特定问题。1)JVM优化,如Java11的ZGC提升了垃圾回收性能。2)标准库改进,如Java9的模块系统减少平台相关问题。3)第三方库提供平台优化版本,如OpenCV。

说明JVM执行的字节码验证的过程。说明JVM执行的字节码验证的过程。May 02, 2025 am 12:18 AM

JVM的字节码验证过程包括四个关键步骤:1)检查类文件格式是否符合规范,2)验证字节码指令的有效性和正确性,3)进行数据流分析确保类型安全,4)平衡验证的彻底性与性能。通过这些步骤,JVM确保只有安全、正确的字节码被执行,从而保护程序的完整性和安全性。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

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

AI Clothes Remover

AI Clothes Remover

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

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一个PHP/MySQL的Web应用程序,非常容易受到攻击。它的主要目标是成为安全专业人员在合法环境中测试自己的技能和工具的辅助工具,帮助Web开发人员更好地理解保护Web应用程序的过程,并帮助教师/学生在课堂环境中教授/学习Web应用程序安全。DVWA的目标是通过简单直接的界面练习一些最常见的Web漏洞,难度各不相同。请注意,该软件中

WebStorm Mac版

WebStorm Mac版

好用的JavaScript开发工具

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)