搜尋
首頁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
如何將Maven或Gradle用於高級Java項目管理,構建自動化和依賴性解決方案?如何將Maven或Gradle用於高級Java項目管理,構建自動化和依賴性解決方案?Mar 17, 2025 pm 05:46 PM

本文討論了使用Maven和Gradle進行Java項目管理,構建自動化和依賴性解決方案,以比較其方法和優化策略。

如何使用適當的版本控制和依賴項管理創建和使用自定義Java庫(JAR文件)?如何使用適當的版本控制和依賴項管理創建和使用自定義Java庫(JAR文件)?Mar 17, 2025 pm 05:45 PM

本文使用Maven和Gradle之類的工具討論了具有適當的版本控制和依賴關係管理的自定義Java庫(JAR文件)的創建和使用。

如何使用咖啡因或Guava Cache等庫在Java應用程序中實現多層緩存?如何使用咖啡因或Guava Cache等庫在Java應用程序中實現多層緩存?Mar 17, 2025 pm 05:44 PM

本文討論了使用咖啡因和Guava緩存在Java中實施多層緩存以提高應用程序性能。它涵蓋設置,集成和績效優勢,以及配置和驅逐政策管理最佳PRA

如何將JPA(Java持久性API)用於具有高級功能(例如緩存和懶惰加載)的對象相關映射?如何將JPA(Java持久性API)用於具有高級功能(例如緩存和懶惰加載)的對象相關映射?Mar 17, 2025 pm 05:43 PM

本文討論了使用JPA進行對象相關映射,並具有高級功能,例如緩存和懶惰加載。它涵蓋了設置,實體映射和優化性能的最佳實踐,同時突出潛在的陷阱。[159個字符]

Java的類負載機制如何起作用,包括不同的類載荷及其委託模型?Java的類負載機制如何起作用,包括不同的類載荷及其委託模型?Mar 17, 2025 pm 05:35 PM

Java的類上載涉及使用帶有引導,擴展程序和應用程序類負載器的分層系統加載,鏈接和初始化類。父代授權模型確保首先加載核心類別,從而影響自定義類LOA

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脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
3 週前By尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
3 週前By尊渡假赌尊渡假赌尊渡假赌
WWE 2K25:如何解鎖Myrise中的所有內容
1 個月前By尊渡假赌尊渡假赌尊渡假赌

熱工具

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser是一個安全的瀏覽器環境,安全地進行線上考試。該軟體將任何電腦變成一個安全的工作站。它控制對任何實用工具的訪問,並防止學生使用未經授權的資源。

WebStorm Mac版

WebStorm Mac版

好用的JavaScript開發工具

mPDF

mPDF

mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

DVWA

DVWA

Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中