搜尋
首頁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 07, 2025 pm 04:53 PM

JavaachievesPlatFormIndependencEthroughByTeCodeAndthejvm.1)sodiscompiledIntobyTecode,notmachinecode.2)thejvminterpretsbytbybytecodeonanyplatform,確保“ writeononce,runany where。”

平台獨立性如何使企業級的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。

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

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

MantisBT

MantisBT

Mantis是一個易於部署的基於Web的缺陷追蹤工具,用於幫助產品缺陷追蹤。它需要PHP、MySQL和一個Web伺服器。請查看我們的演示和託管服務。

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具