亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java中Optional的orElse操作及orElse與orElseGet的區(qū)別詳解

 更新時間:2025年05月02日 09:15:58   作者:小學雞!  
Optional中orElse可能導致空指針異常,orElseGet可以避免這種情況,這篇文章主要介紹了Java中Optional的orElse操作及orElse與orElseGet區(qū)別的相關(guān)資料,文中給出了詳細的代碼示例,需要的朋友可以參考下

1. 大概說明

這篇文章的目的是為了說明:

  • orElse 如何使用
  • orElseGet 如何使用
  • 兩者的區(qū)別

備注:orElse 可能導致 NullPointerException,當 orElse 的參數(shù)是間接計算得來的時候。雖然這種說法有點牽強(因為并不是orElse導致了空指針異常),但是使用 orElseGet 確實可以避免這種情況。

2. 詳細分析

2.1 .orElse 操作

先看個例子:

Optional<String> optional = Optional.empty();
System.out.println(optional.isPresent); // ---->輸出:false
// 返回 false,表示 Optional 里沒有值。

解析:

  • Optional.empty() 代表 一個空的 Optional 實例,即 Optional 沒有值。
  • Optional.ofNullable(null) 等價于 Optional.empty()。

2.2 .orElse 的作用:避免空指針異常

  • 如果 Optional 為空(即 Optional.empty()),就返回 orElse() 里提供的默認值。
  • 如果 Optional 有值,就直接返回這個值,不執(zhí)行 orElse() 提供的默認值。

注意:不管 Optional 為不為空,這個值都會創(chuàng)建,只不過為空時,才使用

// 舉例:當Optional為空時,orElse()才會觸發(fā)
String result = Optional.ofNullable(null)
    .orElse("默認值");
System.out.println(result); // ---->輸出:默認值
// 再舉個例子:
Map<Long, List<String>> map = new HashMap<>();
map.put(1L, Arrays.asList("A", "B", "C"));

List<String> result = Optional.ofNullable(map.get(1L))
    .orElse(Collections.emptyList()); // 為null就返回 空列表
System.out.println(result);  // ---->輸出:[A, B, C] (orElse() 沒起作用)

2.3 為什么要用?

List<String> result = Optional.ofNullable(map.get(0L))
    .orElse(Collections.emptyList())
    .stream();

如果 map.get(0L) == null,那么:

  • 不加 .orElse(Collections.emptyList()) → .stream() 會報 NullPointerException ?
  • 加了 .orElse(Collections.emptyList()) → .stream() 能正常執(zhí)行 ?

2.4 orElseGet如何使用

再來看看 orElseGet 中如何使用:

orElseGet 作用:獲取數(shù)據(jù)并且設(shè)置數(shù)據(jù)為空時的默認值。如果數(shù)據(jù)不為空就能獲取到該數(shù)據(jù);如果為空則返回傳入的參數(shù)來創(chuàng)建對象。

具體的使用案例可看下圖:

2.5 orElse和orElseGet的區(qū)別

orElse() 和 orElseGet() 都是Optional 類中的方法,用于在 Optional 為空時提供默認值。但它們的區(qū)別在于 默認值的獲取方式

1、orElse(T other)

  • 直接傳遞一個默認值
  • 即使 Optional里有值,也會創(chuàng)建 other 對象,但不會使用它
  • 適用于默認值創(chuàng)建代價較低的情況

2、orElseGet(Supplier<? extends T> supplier)

  • 傳遞的是一個 Supplier(懶加載:只有需要的時候才會創(chuàng)建)接口,它是一個函數(shù)式接口,形式是這樣的:()->{ return computedResult },即入?yún)榭?,有返回值(任意類型的?/li>
  • 僅當 Optional 為空時才會執(zhí)行 supplier.get(),不會提前創(chuàng)建默認值
  • 適用于默認值創(chuàng)建代價較高的情況

看個例子:

class User {
    // 中文名
	private String chineseName;
	// 英文名
	private EnglishName englishName;
}

class EnglishName {
    // 全名
    private String fullName;
    // 簡寫
    private String shortName;
}

假如我們現(xiàn)在有 User 類,用戶注冊賬號時,需要提供自己的中文名或英文名,或都提供,我們抽象出一個EnglishName 類,它包含英文名的全名和簡寫(因為有的英文名確實太長了)?,F(xiàn)在,我們希望有一個User.getName() 方法,它可以像下面這樣實現(xiàn):

class User {
    // ... 之前的內(nèi)容
    public String getName1() {
        return Optional.ofNullable(chineseName)
                .orElse(englishName.getShortName());
    }
    
    public String getName2() {
        return Optional.ofNullable(chineseName)
                .orElseGet(() -> englishName.getShortName());
    }
}

寫了兩個版本,分別使用 orElse 和 orElseGet。現(xiàn)在,你可以看出 getName1() 方法有什么風險了嗎?它會出現(xiàn)空指針異常嗎?----> 是的。當用戶只提供了中文名時,此時 englishName 屬性是 null,但是在 orElse 中,englishName.getShortName()總是會執(zhí)行。而在 getName2() 中,這個風險卻沒有。

再舉個例子:

public class Test {
    public static void main(String[] args) {
        System.out.println("orElse() 的情況:");
        String result1 = Optional.ofNullable("實際值")
            .orElse(test2());
        System.out.println("最終結(jié)果: " + result1);

        System.out.println("orElseGet() 的情況:");
        String result2 = Optional.ofNullable("實際值")
            .orElseGet(() -> test2());
        System.out.println("最終結(jié)果: " + result2);
    }

    public static String test2() {
        System.out.println("執(zhí)行昂貴的計算...");
        return "昂貴默認值";
    }
}

輸出:

orElse() 的情況:
執(zhí)行昂貴的計算...
最終結(jié)果: 實際值

orElseGet() 的情況:
最終結(jié)果: 實際值

總結(jié)

到此這篇關(guān)于Java中Optional的orElse操作及orElse與orElseGet區(qū)別詳解的文章就介紹到這了,更多相關(guān)Java Optional的orElse操作內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:

相關(guān)文章

  • 詳解Java I/O流中的字符流有哪些

    詳解Java I/O流中的字符流有哪些

    字節(jié)流的功能已經(jīng)十分強大,幾乎可以直接或間接地處理任何類型的輸入/輸出操作,但它卻不能直接操作16位的Unicode字符,這就需要使用字符流,所以在今天的內(nèi)容中,小編會給大家講解IO流中的字符流,希望各位能夠繼續(xù)耐心學習
    2023-10-10
  • eclipse springboot工程打war包方法及再Tomcat中運行的方法

    eclipse springboot工程打war包方法及再Tomcat中運行的方法

    這篇文章主要介紹了eclipse springboot工程打war包方法及再Tomcat中運行的方法,本文圖文并茂給大家介紹的非常詳細,具有一定的參考借鑒價值,需要的朋友可以參考下
    2019-08-08
  • SpringBoot+aop實現(xiàn)主從數(shù)據(jù)庫的讀寫分離操作

    SpringBoot+aop實現(xiàn)主從數(shù)據(jù)庫的讀寫分離操作

    讀寫分離的作用是為了緩解寫庫,也就是主庫的壓力,但一定要基于數(shù)據(jù)一致性的原則,就是保證主從庫之間的數(shù)據(jù)一定要一致,這篇文章給大家介紹SpringBoot+aop實現(xiàn)主從數(shù)據(jù)庫的讀寫分離操作,感興趣的朋友跟隨小編一起看看吧
    2024-03-03
  • Java多線程之中斷線程(Interrupt)的使用詳解

    Java多線程之中斷線程(Interrupt)的使用詳解

    interrupt字面上是中斷的意思,但在Java里Thread.interrupt()方法實際上通過某種方式通知線程,并不會直接中止該線程
    2013-05-05
  • SpringBoot Java后端實現(xiàn)okhttp3超時設(shè)置的方法實例

    SpringBoot Java后端實現(xiàn)okhttp3超時設(shè)置的方法實例

    Okhttp的使用沒有httpClient廣泛,網(wǎng)上關(guān)于Okhttp設(shè)置代理的方法很少,下面這篇文章主要給大家介紹了關(guān)于SpringBoot Java后端實現(xiàn)okhttp3超時設(shè)置的相關(guān)資料,需要的朋友可以參考下
    2021-10-10
  • 一篇文章帶你深入了解Java類加載

    一篇文章帶你深入了解Java類加載

    這篇文章主要介紹了Java中類加載過程全面解析,具有一定參考價值,需要的朋友可以了解下,希望能給你帶來幫助
    2021-08-08
  • MyBatisPlus條件構(gòu)造器的實現(xiàn)示例

    MyBatisPlus條件構(gòu)造器的實現(xiàn)示例

    本文主要介紹了MyBatisPlus條件構(gòu)造器的實現(xiàn)示例,主要包括了QueryWrapper,UpdateWrapper,LambdaQueryWrapper,LambdaUpdateWrapper這四種,具有一定的參考價值,感興趣的可以了解下
    2023-12-12
  • java小程序火鍋店點餐系統(tǒng)

    java小程序火鍋店點餐系統(tǒng)

    這篇文章主要介紹了java小程序火鍋店點餐系統(tǒng),采用Java語言和Vue技術(shù),以小程序模式實現(xiàn)的火鍋點菜系統(tǒng),文中提供了解決思路和部分實現(xiàn)代碼,需要的朋友可以參考下
    2023-03-03
  • 淺析Java數(shù)據(jù)庫操作工具包jOOQ的使用

    淺析Java數(shù)據(jù)庫操作工具包jOOQ的使用

    jOOQ?是一個輕量級的?Java?ORM(對象關(guān)系映射)框架,可用來構(gòu)建復雜的?SQL?查詢,這篇文章主要來和大家介紹一下jOOQ的使用,需要的可以參考下
    2024-04-04
  • java實現(xiàn)小貓釣魚游戲

    java實現(xiàn)小貓釣魚游戲

    這篇文章主要為大家詳細介紹了java實現(xiàn)小貓釣魚游戲,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01

最新評論