欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

淺談Java8的特性之Optional類

 更新時間:2023年08月14日 10:32:59   作者:Pluto372  
這篇文章主要介紹了淺談Java8的特性之Optional類,Optional類是 Java 8 引入的一個很有趣的特性,Optional 類是一個可以為null的容器對象,它主要解決的問題是臭名昭著的空指針異常,需要的朋友可以參考下

一、Optional類 簡介

Optional類是 Java 8 引入的一個很有趣的特性。它主要解決的問題是臭名昭著的空指針異常(NullPointerException)

  • Optional 類是一個可以為null的容器對象。如果值存在則isPresent()方法會返回true,調(diào)用get()方法會返回該對象。
  • Optional 是個容器:它可以保存類型T的值,或者僅僅保存null。Optional提供很多有用的方法,這樣我們就不用顯式進(jìn)行空值檢測。
  • Optional 類的引入很好的解決空指針異常。

Optional 是一個對象容器,具有以下兩個特點(diǎn):

  • 提示用戶要注意該對象有可能為null
  • 簡化if else代碼

舉一個簡單的例子,在 Java 8 之前,任何訪問對象方法或?qū)傩缘恼{(diào)用都可能導(dǎo)致 NullPointerException:

用戶 -> 家庭住址  -> 城市  ->郵編
String postCode = user.getAddress().getCity().getPostCode();

在這個示例中,為了避免異常,就得在訪問每一個值之前對其進(jìn)行明確地檢查:

if (user != null) {
    Address address = user.getAddress();
    if (address != null) {
        City city= address.getCity();
        if (city != null) {
            String postCode = city.getPostCode();
            if (postCode != null) {
            	//對postCode進(jìn)行操作
               test(postCode);
            }
        }
    }
}

這很容易就變得冗長,難以維護(hù)。 為了簡化這個過程,我們就可以用 Optional 類。

二、Optional類的使用

1. 創(chuàng)建:

Optional類的實例創(chuàng)建有三種方式:

  • Optional.empty() :創(chuàng)建一個空的 Optional 實例。
  • Optional.of(T t) :創(chuàng)建一個 Optional 實例,當(dāng) t為null時拋出異常(NullPointerException)。
  • Optional.ofNullable(T t) :創(chuàng)建一個 Optional 實例,但當(dāng) t為null時不會拋出異常,而是返回一個空的實例。

2. 獲?。?/h3>
  • get():獲取optional實例中的對象,當(dāng)optional 容器為空時報錯。

3. 判斷:

  • isPresent():判斷optional是否為空,如果空則返回false,否則返回true
  • ifPresent(Consumer c):如果optional不為空,則將optional中的對象傳給Comsumer函數(shù)
public class OptionalDemo {
    public static void main(String[] args) {
        User user = new User("王也", "5");
        User userNull= null;
        Optional<User> optional = Optional.ofNullable(user);
        System.out.println(optional.isPresent());
        optional.ifPresent(u -> System.out.println("optional不為null  "+u));
    }
}

在這里插入圖片描述

  • orElse(T other):如果optional不為空,則返回optional中的對象;如果為null,則返回 other 這個默認(rèn)值
   User user = new User("王也", "5");
   User userNull= null;
   //orElse的工作方式非常直接,如果有值則返回該值,否則返回傳遞給它的參數(shù)值:
   User user1 = Optional.ofNullable(userNull).orElse(user);
   System.out.println(user1);
   //控制臺輸出:User(name=王也, age=5)
  • orElseGet(Supplier other):如果optional不為空,則返回optional中的對象;如果為null,則使用Supplier函數(shù)生成默認(rèn)值other
  User user1 = Optional.ofNullable(userNull).orElseGet(()->user );
  //結(jié)果同上
  • orElseThrow(Supplier exception):如果optional不為空,則返回optional中的對象;如果為null,則拋出Supplier函數(shù)生成的異常
//這個方法讓我們有更豐富的語義,可以決定拋出什么樣的異常,而不總是拋出 NullPointerException。
 User result = Optional.ofNullable(userNull)
      .orElseThrow( () -> new IllegalArgumentException());

orElse() 和 orElseGet() 的不同之處

乍一看,這兩種方法似乎起著同樣的作用。然而事實并非如此。我們創(chuàng)建一些示例來突出二者行為上的異同。

(1)當(dāng)對象為空時:

public class OptionalDemo {
    public static void main(String[] args) {
        User userNull = null;
        System.out.println("使用orElse():");
        User result = Optional.ofNullable(userNull).orElse(createNewUser());
        System.out.println("使用orElseGet():");
        User result2 = Optional.ofNullable(userNull).orElseGet(() -> createNewUser());
    }
    private static User createNewUser() {
        System.out.println("Creating New User");
        return new User("新的user對象", "1234");
    }
}

上面的代碼中,兩種方法都調(diào)用了 createNewUser() 方法,這個方法會記錄一個消息并返回 User 對象。

控制臺輸出:

使用orElse():
Creating New User
使用orElseGet():
Creating New User

由此可見,當(dāng)對象為空而返回默認(rèn)對象時,行為并無差異。

(2)當(dāng)對象不為空時:

public class OptionalDemo {
    public static void main(String[] args) {
        User user = new User("王也", "5");
        System.out.println("使用orElse():");
        User result = Optional.ofNullable(user).orElse(createNewUser());
        System.out.println("使用orElseGet():");
        User result2 = Optional.ofNullable(user).orElseGet(() -> createNewUser());
    }
    private static User createNewUser() {
        System.out.println("Creating New User");
        return new User("新的user對象", "1234");
    }
}

控制臺輸出:

使用orElse():
Creating New User
使用orElseGet():

這個示例中,兩個 Optional 對象都包含非空值,兩個方法都會返回對應(yīng)的非空值。不過,orElse() 方法仍然創(chuàng)建了 User 對象。與之相反,orElseGet() 方法不創(chuàng)建 User 對象。

在執(zhí)行較密集的調(diào)用時,比如調(diào)用 Web 服務(wù)或數(shù)據(jù)查詢,這個差異會對性能產(chǎn)生重大影響。

4. 過濾:

filter(Predicate p):filter() 接受一個 Predicate 參數(shù),返回測試結(jié)果為 true 的值。如果測試結(jié)果為 false,會返回一個空的 Optional。

5. 映射:

  • map(Function<T, U> mapper):如果optional不為空,則將optional中的對象 t 映射成另外一個對象 u,并將 u 存放到一個新的optional容器中。
  • flatMap(Function<T,Optional > mapper):跟上面一樣,在optional不為空的情況下,將對象t映射成另外一個optional

map() 對值應(yīng)用(調(diào)用)作為參數(shù)的函數(shù),然后將返回的值包裝在 Optional 中。這就使對返回值進(jìn)行鏈試調(diào)用的操作成為可能 —— 這里的下一環(huán)就是 orElse()。

flatMap() 也需要函數(shù)作為參數(shù),并對值調(diào)用這個函數(shù),然后直接返回結(jié)果。

過濾和映射的示例

public class OptionalDemo {
    public static void main(String[] args) {
        List<Student> studentList = initData();
        for (Student student : studentList) {
            Optional<Student> studentOptional = Optional.of(student);
            Integer score = studentOptional.filter(s -> s.getAge() >= 18).map(Student::getScore).orElse(0);
            if (score > 80) {
                System.out.println("入選:" + student.getName());
            }
        }
    }
    private static List<Student> initData(){
        Student s1 = new Student("張三", 19, 80);
        Student s2 = new Student("李四", 19, 50);
        Student s3 = new Student("王五", 23, null);
        Student s4 = new Student("趙六", 16, 90);
        Student s5 = new Student("錢七", 18, 99);
        Student s6 = new Student("孫八", 20, 40);
        Student s7 = new Student("吳九", 21, 88);
        return Arrays.asList(s1, s2, s3, s4, s5, s6, s7);
    }
}

使用stream流的寫法:

 public static void main(String[] args) {
        List<Student> studentList = initData();
        List<String> studentName = studentList.stream().filter(student -> student.getAge() >= 18)
                .filter(student -> student.getScore() != null && student.getScore() > 80)
                .map(student -> student.getName()).collect(Collectors.toList());
        System.out.println(studentName);
    }

控制臺輸出:

入選:錢七
入選:吳九

到此這篇關(guān)于淺談Java8的特性之Optional類的文章就介紹到這了,更多相關(guān)Java的Optional類內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java List分頁功能實現(xiàn)代碼實例

    Java List分頁功能實現(xiàn)代碼實例

    這篇文章主要介紹了Java List分頁功能實現(xiàn)代碼實例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-01-01
  • Java如何實現(xiàn)驗證碼驗證功能

    Java如何實現(xiàn)驗證碼驗證功能

    這篇文章主要教大家如何實現(xiàn)Java驗證碼驗證功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2018-02-02
  • Java對List進(jìn)行排序的方法總結(jié)

    Java對List進(jìn)行排序的方法總結(jié)

    在Java中,對List進(jìn)行排序是一項常見的任務(wù),Java提供了多種方法來對List中的元素進(jìn)行排序,本文將詳細(xì)介紹如何使用Java來實現(xiàn)List的排序操作,涵蓋了常用的排序方法和技巧,需要的朋友可以參考下
    2024-07-07
  • 對java for 循環(huán)執(zhí)行順序的詳解

    對java for 循環(huán)執(zhí)行順序的詳解

    今天小編就為大家分享一篇對java for 循環(huán)執(zhí)行順序的詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-06-06
  • Java的GUI編程之列表和組合框的設(shè)計使用

    Java的GUI編程之列表和組合框的設(shè)計使用

    這篇文章主要介紹了Java的GUI編程之列表和組合框的設(shè)計使用,是Java圖形界面編程中的基礎(chǔ)知識,需要的朋友可以參考下
    2015-10-10
  • 一文詳解Elasticsearch和MySQL之間的數(shù)據(jù)同步問題

    一文詳解Elasticsearch和MySQL之間的數(shù)據(jù)同步問題

    Elasticsearch中的數(shù)據(jù)是來自于Mysql數(shù)據(jù)庫的,因此當(dāng)數(shù)據(jù)庫中的數(shù)據(jù)進(jìn)行增刪改后,Elasticsearch中的數(shù)據(jù),索引也必須跟著做出改變。本文主要來和大家探討一下Elasticsearch和MySQL之間的數(shù)據(jù)同步問題,感興趣的可以了解一下
    2023-04-04
  • java實現(xiàn)文件復(fù)制、剪切文件和刪除示例

    java實現(xiàn)文件復(fù)制、剪切文件和刪除示例

    這篇文章主要介紹了java實現(xiàn)文件復(fù)制、剪切文件和刪除示例,需要的朋友可以參考下
    2014-04-04
  • Spring Data JPA分頁復(fù)合查詢原理解析

    Spring Data JPA分頁復(fù)合查詢原理解析

    這篇文章主要介紹了Spring Data JPA分頁復(fù)合查詢原理解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-11-11
  • Java多線程編程中的線程死鎖的問題解決

    Java多線程編程中的線程死鎖的問題解決

    線程死鎖是多線程編程中的一個常見問題,它發(fā)生在多個線程互相等待對方釋放資源的情況下,導(dǎo)致程序無法繼續(xù)執(zhí)行,本文就來介紹一下Java多線程編程中的線程死鎖的問題解決,感興趣的可以了解一下
    2023-08-08
  • Springboot集成Protobuf的流程步驟

    Springboot集成Protobuf的流程步驟

    在以往的項目中進(jìn)行網(wǎng)絡(luò)通信和數(shù)據(jù)交換的應(yīng)用場景中,最經(jīng)常使用的技術(shù)便是json或xml,但是今天在介紹一個Google的力作protobuf作為數(shù)據(jù)交換格式,文中給大家介紹了Springboot集成Protobuf的流程步驟,需要的朋友可以參考下
    2024-03-03

最新評論