最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

stream.findFirst().get()?報(bào)錯(cuò)?NoSuchElementException的解決方案

 更新時(shí)間:2025年12月09日 15:23:43   作者:北極糊的狐  
文章講述了在使用Java?Stream?API時(shí),stream.findFirst().get()報(bào)錯(cuò)NoSuchElementException的原因,以及如何通過(guò)Optional提供的安全方法來(lái)修復(fù)這個(gè)問(wèn)題,本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧

stream.findFirst().get() 報(bào)錯(cuò) NoSuchElementException,核心原因是:Stream 流中沒(méi)有匹配到任何元素,findFirst() 返回空的 Optional 對(duì)象,此時(shí)調(diào)用 get() 會(huì)直接拋出異常(Optional.get() 約定:空 Optional 調(diào)用 get () 必拋異常)。

一、報(bào)錯(cuò)根源拆解

1. 關(guān)鍵邏輯:Optional 的設(shè)計(jì)初衷

findFirst() 返回 Optional<T> 類型,目的是「明確告知調(diào)用者:結(jié)果可能為空」,強(qiáng)制開(kāi)發(fā)者處理 “無(wú)結(jié)果” 的場(chǎng)景。而直接調(diào)用 get() 相當(dāng)于 “無(wú)視空值風(fēng)險(xiǎn)”,一旦流為空就會(huì)報(bào)錯(cuò):

// 錯(cuò)誤示例:流為空時(shí),findFirst() 返回 Optional.empty(),get() 拋異常
List<String> list = Collections.emptyList();
String result = list.stream()
                    .filter(s -> s.startsWith("A")) // 無(wú)匹配元素
                    .findFirst()
                    .get(); // 報(bào)錯(cuò):NoSuchElementException: No value present

2. 常見(jiàn)觸發(fā)場(chǎng)景

  • 流的數(shù)據(jù)源為空(如 emptyList()、數(shù)據(jù)庫(kù)查詢無(wú)結(jié)果);
  • filter() 過(guò)濾條件過(guò)于嚴(yán)格,沒(méi)有元素滿足;
  • 流經(jīng)過(guò) map()/flatMap() 后變?yōu)榭樟鳌?/li>

二、解決方案(按安全優(yōu)先級(jí)排序)

核心原則:永遠(yuǎn)不要直接調(diào)用 Optional.get(),除非能 100% 確定流中一定有元素。以下是 5 種安全處理方式,按需選擇:

方案 1:用 orElse() 給默認(rèn)值(最常用)

流為空時(shí),返回預(yù)設(shè)的默認(rèn)值,將.get()替換為.orElse(null)(適合 “無(wú)結(jié)果時(shí)用默認(rèn)值兜底” 的場(chǎng)景):

List<String> list = Collections.emptyList();
// 無(wú)匹配元素時(shí),返回默認(rèn)值 "默認(rèn)值"
String result = list.stream()
                    .filter(s -> s.startsWith("A"))
                    .findFirst()
                    .orElse("默認(rèn)值"); // 安全:不會(huì)拋異常
System.out.println(result); // 輸出:默認(rèn)值

方案 2:用 orElseGet() 延遲生成默認(rèn)值(性能更優(yōu))

與 orElse() 類似,但默認(rèn)值是 “懶加載” 的(只有流為空時(shí)才執(zhí)行 Supplier 邏輯,適合默認(rèn)值生成耗時(shí)的場(chǎng)景,如數(shù)據(jù)庫(kù)查詢、復(fù)雜計(jì)算):

// 無(wú)結(jié)果時(shí),調(diào)用 Supplier 生成默認(rèn)值(延遲執(zhí)行)
String result = list.stream()
                    .filter(s -> s.startsWith("A"))
                    .findFirst()
                    .orElseGet(() -> generateDefaultValue()); // 流為空時(shí)才執(zhí)行 generateDefaultValue()
// 生成默認(rèn)值的方法(示例)
private String generateDefaultValue() {
    System.out.println("生成默認(rèn)值(僅流為空時(shí)執(zhí)行)");
    return "延遲生成的默認(rèn)值";
}

方案 3:用 orElseThrow() 拋?zhàn)远x異常(明確無(wú)結(jié)果是錯(cuò)誤場(chǎng)景)

如果 “流必須有結(jié)果”(如根據(jù) ID 查詢核心配置,無(wú)結(jié)果則系統(tǒng)無(wú)法運(yùn)行),拋出自定義異常,比默認(rèn)的 NoSuchElementException 更易排查:

try {
    String result = list.stream()
                        .filter(s -> s.startsWith("A"))
                        .findFirst()
                        .orElseThrow(() -> new RuntimeException("未找到匹配的元素")); // 自定義異常
} catch (RuntimeException e) {
    // 處理異常(日志記錄、返回錯(cuò)誤響應(yīng)等)
    e.printStackTrace();
}
  • 推薦場(chǎng)景:業(yè)務(wù)上 “無(wú)結(jié)果” 屬于異常情況(如用戶查詢不存在的訂單)。

方案 4:用 ifPresent() 處理非空結(jié)果(無(wú)返回值)

如果只需要 “有結(jié)果時(shí)執(zhí)行某個(gè)邏輯,無(wú)結(jié)果則不做任何事”(如異步通知、日志打?。?,用 ifPresent() 避免空判斷:

list.stream()
    .filter(s -> s.startsWith("A"))
    .findFirst()
    .ifPresent(result -> {
        // 只有流不為空時(shí),才執(zhí)行此邏輯(無(wú)需手動(dòng)判空)
        System.out.println("找到匹配元素:" + result);
        doSomething(result); // 業(yè)務(wù)邏輯
    });

方案 5:用 isPresent() 手動(dòng)判空(最靈活)

先判斷 Optional 是否有值,再?zèng)Q定后續(xù)邏輯(適合需要 “無(wú)結(jié)果時(shí)執(zhí)行復(fù)雜邏輯” 的場(chǎng)景,如返回錯(cuò)誤碼 + 日志記錄):

Optional<String> optional = list.stream()
                                .filter(s -> s.startsWith("A"))
                                .findFirst();
if (optional.isPresent()) {
    String result = optional.get(); // 此時(shí) get() 安全(已判空)
    doSomething(result);
} else {
    // 無(wú)結(jié)果時(shí)的處理邏輯
    System.out.println("未找到匹配元素");
    return "錯(cuò)誤碼";
}

三、進(jìn)階優(yōu)化:避免流為空的前置校驗(yàn)

如果流的數(shù)據(jù)源是集合 / 數(shù)組,可先做前置校驗(yàn),減少流處理的空值風(fēng)險(xiǎn):

List<String> list = Collections.emptyList();
// 前置校驗(yàn):先判斷集合是否為空,再處理流
if (CollectionUtils.isEmpty(list)) { // 用 Apache Commons 工具類,或手動(dòng)判空
    System.out.println("集合為空,直接返回默認(rèn)值");
    return "默認(rèn)值";
}
// 集合非空時(shí),再處理流(減少 Optional 空值概率)
String result = list.stream()
                    .filter(s -> s.startsWith("A"))
                    .findFirst()
                    .orElse("無(wú)匹配元素");

四、常見(jiàn)誤區(qū)提醒

不要用 get() 配合 filter() 判空(冗余且不安全):

// 錯(cuò)誤示例:冗余且仍有風(fēng)險(xiǎn)(若 filter 后為空,get() 仍報(bào)錯(cuò))
Optional<String> optional = list.stream().filter(...).findFirst();
if (optional.filter(Objects::nonNull).isPresent()) { // 多余的 filter
    String result = optional.get();
}

正確做法:直接用 isPresent() 或 ifPresent(),無(wú)需額外 filter(Objects::nonNull)findFirst() 已處理流中元素的空值)。

不要忽略 Optional 的其他有用方法:

map():Optional 非空時(shí),對(duì)結(jié)果做轉(zhuǎn)換(避免嵌套 Optional);

// 示例:找到元素后,轉(zhuǎn)為長(zhǎng)度(無(wú)元素時(shí)返回 0)
int length = list.stream()
                 .filter(s -> s.startsWith("A"))
                 .findFirst()
                 .map(String::length) // 非空時(shí)執(zhí)行 length()
                 .orElse(0); // 空時(shí)返回 0

flatMap():處理結(jié)果為 Optional 的轉(zhuǎn)換(如關(guān)聯(lián)查詢)。

總結(jié)

stream.findFirst().get() 報(bào)錯(cuò)的本質(zhì)是 “未處理空結(jié)果”,修復(fù)的核心是「用 Optional 提供的安全方法替代直接 get ()」。推薦優(yōu)先級(jí):

  1. 有默認(rèn)值 → orElse()/orElseGet()
  2. 無(wú)結(jié)果是異常 → orElseThrow();
  3. 有結(jié)果才執(zhí)行邏輯 → ifPresent()
  4. 需復(fù)雜空值處理 → isPresent() 手動(dòng)判空。

到此這篇關(guān)于stream.findFirst().get() 報(bào)錯(cuò) NoSuchElementException的解決方案的文章就介紹到這了,更多相關(guān)stream.findFirst().get() 報(bào)錯(cuò) NoSuchElementException內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 解決pycharm py文件運(yùn)行后停止按鈕變成了灰色的問(wèn)題

    解決pycharm py文件運(yùn)行后停止按鈕變成了灰色的問(wèn)題

    今天小編就為大家分享一篇解決pycharm py文件運(yùn)行后停止按鈕變成了灰色的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-11-11
  • Python輪子使用之.whl原理與安裝完整指南

    Python輪子使用之.whl原理與安裝完整指南

    WHL文件是以Wheel格式保存的Python安裝包,Wheel是Python發(fā)行版的標(biāo)準(zhǔn)內(nèi)置包格式,這篇文章主要介紹了Python輪子使用之.whl原理與安裝的相關(guān)資料,需要的朋友可以參考下
    2026-01-01
  • Python源碼學(xué)習(xí)之PyType_Type和PyBaseObject_Type詳解

    Python源碼學(xué)習(xí)之PyType_Type和PyBaseObject_Type詳解

    今天給大家?guī)?lái)的是關(guān)于Python源碼的相關(guān)知識(shí)學(xué)習(xí),文章圍繞著PyType_Type和PyBaseObject_Type展開(kāi),文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下
    2021-06-06
  • Python基于面向?qū)ο笞鲆粋€(gè)文件夾整理工具

    Python基于面向?qū)ο笞鲆粋€(gè)文件夾整理工具

    這篇文章主要給大家介紹了Python基于面向?qū)ο笞鲆粋€(gè)文件夾整理工具,文中的示例代碼講解詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-02-02
  • python opencv 檢測(cè)移動(dòng)物體并截圖保存實(shí)例

    python opencv 檢測(cè)移動(dòng)物體并截圖保存實(shí)例

    這篇文章主要介紹了python opencv 檢測(cè)移動(dòng)物體并截圖保存實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-03-03
  • Python對(duì)接六大主流數(shù)據(jù)庫(kù)(只需三步)

    Python對(duì)接六大主流數(shù)據(jù)庫(kù)(只需三步)

    這篇文章主要介紹了Python對(duì)接六大主流數(shù)據(jù)庫(kù)(只需三步),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • Django實(shí)現(xiàn)跨域的2種方法

    Django實(shí)現(xiàn)跨域的2種方法

    這篇文章主要介紹了Django實(shí)現(xiàn)跨域的2中方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-07-07
  • python中with用法講解

    python中with用法講解

    在本篇文章里小編給大家整理的是關(guān)于python中with用法講解內(nèi)容,有需要的朋友們可以參考下。
    2020-02-02
  • python實(shí)現(xiàn)自動(dòng)獲取IP并發(fā)送到郵箱

    python實(shí)現(xiàn)自動(dòng)獲取IP并發(fā)送到郵箱

    這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)自動(dòng)獲取IP并發(fā)到郵箱,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • opencv檢測(cè)動(dòng)態(tài)物體的實(shí)現(xiàn)

    opencv檢測(cè)動(dòng)態(tài)物體的實(shí)現(xiàn)

    本文主要介紹了opencv檢測(cè)動(dòng)態(tài)物體的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-07-07

最新評(píng)論

南汇区| 沙洋县| 通化县| 卢氏县| 辛集市| 乌拉特后旗| 景谷| 修水县| 苏尼特左旗| 徐闻县| 宜川县| 鸡泽县| 横山县| 千阳县| 三亚市| 红原县| 秭归县| 璧山县| 宜州市| 和平县| 英德市| 明星| 南宫市| 洪江市| 卢氏县| 桃园市| 喀什市| 上栗县| 清水河县| 太白县| 苏尼特左旗| 渝中区| 明水县| 岳阳市| 南汇区| 株洲市| 新巴尔虎右旗| 独山县| 印江| 始兴县| 化德县|