Kotlin集合與空值

我們已經學習了 Kotlin 中的空安全(null safety)。在本節中,我們將討論如何處理集合中的空值(null),因為集合比其他數據類型更復雜。我們還將討論如何處理可空元素時常用的便利方法。

集合與空值

可空集合和具有可空元素的非空集合是同一枚硬幣的兩面。此外,我們還需要認識到空集合和可空集合之間的區別。讓我們看看四種情況:

val list = listOf<String>()var nullableList: List<Int>? = listOf<Int>(1, 2, 4, 6)val listWithNullableElements: List<Int?> = listOf<Int?>(1, 2, 4, null, null)var absolutelyNullableList: List<Int?>? = listOf<Int?>(1, 2, 4, null, null)

第一種情況:我們有一個簡單的空列表。我們可以像對待常規列表一樣處理它,并不需要擔心空指針異常(NullPointerException)。這個列表是實際的且非空的,只是為空。

第二種情況:我們有一個可空的列表:這樣的列表中的元素不可為空,必須是實際的整數。但變量 nullableList 本身可以為空。在使用可空列表時,我們需要使用安全調用運算符(?.)、空值合并運算符(?:)等操作,例如:

val list: List<Int> = nullableList ?: listOf<Int>()

第三種情況:我們有一個具有可空元素的列表。該列表的類型是非空的,但其中的元素可以為空。

val num: Int = listWithNullableElements[1] ?: 150

第四種情況:我們結合了第二種和第三種情況:

val num: Int = absolutelyNullableList?.get(1) ?: 150

基本原則是:如果可以返回一個空集合,最好返回空集合,而不是返回 null,避免使用可空類型。然而,有時我們確實需要處理可空集合。例如,如果我們聲明了一個可以接收值或 null 的變量(var 而不是 val),那么 null 就相當于“無元素”,“沒有答案”或“沒有結果”。

從包含空值的序列創建非空集合

有時你會遇到包含空值的元素序列,而你需要使用這些序列創建一個沒有空值的集合。在這種情況下,可以使用特定的函數 listOfNotNull()setOfNotNull(),它們幫助我們刪除所有空值并返回默認的只讀非空集合。讓我們來看一下它是如何工作的:

val list = listOfNotNull(1, null, 50, 404, 42, null, 42, 404) // [1, 50, 404, 42, 42, 404]
val set = setOfNotNull(1, null, 50, 404, 42, null, 42, 404) // [1, 50, 404, 42]

所有空值元素都被從新集合中刪除。如果你的元素序列只有空值,這些方法將返回一個空集合(非空!)。記住,如果你需要一個可變集合,可以通過 toMutableList()toMutableSet() 將其轉換為可變集合。

可空集合的函數

Kotlin 提供了一些方便的工具來處理具有可空元素的集合:isNullOrEmpty()getOrNull()firstOrNull()lastOrNull()randomOrNull()。讓我們來看看它們!

  • isNullOrEmpty():如果集合為空或為 null,則返回 true。否則返回 false
val emptySet: Set<Int>? = setOf()
val nullSet: Set<Int>? = null
val set = setOf<Int?>(null, null)println(emptySet.isNullOrEmpty()) // true,因為集合為空
println(nullSet.isNullOrEmpty()) // true,因為集合為 null
println(set.isNullOrEmpty()) // false,因為集合中有兩個空值元素
  • getOrNull():返回列表或數組中的一個元素,如果該元素不存在,則返回 null(不能用于 Set)。
val list = listOf(0, 1, 2)
println(list.getOrNull(2)) // 2
println(list.getOrNull(3)) // null,因為這個列表沒有第四個元素,索引從 0 開始

你可以使用 list[3] 代替,但這樣會引發異常,而 getOrNull() 則會在任何情況下返回一個值。

  • randomOrNull():像 getOrNull() 一樣,如果集合為空,它返回 null,否則返回一個隨機元素。
val list = listOf(0, 1, 2)
val list1 = listOf<Int>()println(list.randomOrNull()) // 返回一個元素
println(list1.randomOrNull()) // null,因為集合為空

firstOrNull()lastOrNull():允許我們設置特定的條件。如果集合中至少有一個元素滿足條件,它們會返回該元素。
區別是:

  • firstOrNull() 會返回集合中 第一個滿足條件的元素。如果沒有滿足條件的元素,它會返回 null

  • lastOrNull() 會返回集合中 最后一個滿足條件的元素。如果沒有滿足條件的元素,它也會返回 null

val list = listOf(0, 1, 1, 2, 5, 7, 6)
val num = list.firstOrNull { it > 3 }
val num1 = list.lastOrNull { it == 1 }

最小值和最大值(可空)

Kotlin 為集合提供了許多方便的比較工具——包括處理可空元素的工具。以下是它們的簡介:

  • minOrNull() / maxOrNull():返回集合中的最大或最小元素,如果集合為空,則返回 null

  • minByOrNull() / maxByOrNull():返回滿足條件的最大或最小元素,如果沒有符合條件的元素,則返回 null

  • minOfOrNull() / maxOfOrNull():返回元素特性(如值、大小等)上的最大或最小值,若集合為空則返回 null

  • minWithOrNull() / maxWithOrNull():返回滿足條件的最大或最小元素,指定了 compareBy {} 塊。

  • minOfWithOrNull() / maxOfWithOrNull():返回符合條件的元素特性上的最大或最小值,指定了 compareBy {} 塊。

我們這里只提到這些函數,詳細的示例和講解可以參考“集合的聚合操作”一節。

有一點需要注意:這些函數都有沒有 “OrNull” 后綴的對應版本。曾幾何時,這些“沒有 OrNull” 的函數是合法的工具。但從 Kotlin 1.4.0 開始,這些函數(如 min()max()minBy()maxBy()minWith()maxWith())被重命名為 minOrNull()maxOrNull() 等,且老版本的函數已標記為廢棄。到了 Kotlin 1.7.0,這些廢棄的函數重新引入,作為它們各自 “OrNull” 對應版本的非空替代品。這些非空版本返回一個集合元素,或者在集合為空時拋出異常。所以使用時要小心!

結論

我們已經討論了如何處理具有可空元素的集合以及一些便捷的方法。以下是幾個要點:

  • Kotlin 中有可空集合、具有可空元素的集合和空集合,它們是不同的。

  • listOfNotNull()setOfNotNull() 函數幫助我們從包含空值的序列中創建非空集合。

  • 我們可以檢查集合是否為空,或者集合中是否有元素滿足某些條件,確保不會拋出異常。

  • 我們可以使用比較函數如 minOrNull()maxOrNull() 等,選擇并顯示集合元素或其特性。

  • 這些函數有對應的非空版本,它們在集合為空時會拋出異常,而不是返回 null

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/89885.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/89885.shtml
英文地址,請注明出處:http://en.pswp.cn/web/89885.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

nextjs編程式跳轉

Next.js 中&#xff0c;你可以通過多種方式實現編程式導航&#xff08;即通過代碼而非 <Link> 組件跳轉頁面&#xff09;。以下是完整的實現方法&#xff1a; 1. 使用 useRouter Hook&#xff08;函數組件&#xff09; 這是最常用的方法&#xff0c;適用于函數組件&#…

Git Remote命令介紹:遠程倉庫管理

一、Git Remote 是什么 git remote主要用于管理遠程倉庫&#xff0c;可以輕松地與遠程倉庫進行交互&#xff0c;實現代碼的共享與同步 。 二、Git Remote 的作用 &#xff08;一&#xff09;連接橋梁 假設你正在參與一個大型的 Web 應用開發項目&#xff0c;團隊成員分布在…

Android開發中的11種行為型設計模式深度解析

在Android應用開發中&#xff0c;設計模式是解決特定問題的可重用方案&#xff0c;其中行為型設計模式尤其重要&#xff0c;它們專注于對象之間的通信和職責分配。本文將深入解析Android開發中最常用的11種行為型設計模式&#xff0c;每個模式都配有詳細的介紹和實際應用示例&a…

Python 模塊未找到?這樣解決“ModuleNotFoundError”

在 Python 開發中&#xff0c;遇到“ModuleNotFoundError”時&#xff0c;通常是因為 Python 解釋器無法找到你嘗試導入的模塊。這可能是由于多種原因導致的&#xff0c;比如模塊未安裝、路徑不正確、虛擬環境未激活等。今天&#xff0c;就讓我們一起探討如何解決“ModuleNotFo…

Numpy庫,矩陣形狀與維度操作

目錄 一.numpy庫簡介與安裝 numpy庫的安裝 二.numpy核心功能 1.矩陣處理 2.數學運算 三.數據的維度與屬性 1.維度管理 2.屬性方法 四.數據類型與存儲范圍 五.矩陣形狀與維度操作 六.數據升維與reshape()方法 一.numpy庫簡介與安裝 NumPy是Python中用于科學計算的核心…

圖論(2):最短路

最短路一、模板1. Floyd2. 01BFS3. SPFA4. Dijkstra&#xff08;弱化版&#xff09;5. Dijkstra&#xff08;優化版&#xff09;二、例題1. Floyd1.1 傳送門1.2 無向圖最小環1.3 災后重建1.4 飛豬2. 01BFS2.1 Kathiresan2.2 障礙路線2.3 奇妙的棋盤3. SPFA3.1 奶牛派對3.2 營救…

“融合進化,智領未來”電科金倉引領數字化轉型新紀元

一、融合進化 智領未來電科金倉2025產品發布會重磅開啟&#xff01; 7月15日&#xff0c;以“融合進化 智領未來”為主題的電科金倉2025產品發布會在北京舉辦。產品發布會上展示了四款代表未來數字化趨勢的創新性產品。這些產品不僅涵蓋了數據庫技術&#xff0c;還涉及到數據集…

常規筆記本和加固筆記本的區別

在現代科技產品中&#xff0c;筆記本電腦因其便攜性和功能性被廣泛應用。根據使用場景和需求的不同&#xff0c;筆記本可分為常規筆記本和加固筆記本&#xff0c;二者在多個方面存在顯著區別。適用場景是區分二者的重要標志。常規筆記本主要面向普通消費者和辦公人群&#xff0…

Shell 腳本編程全面學習指南

前言Shell 腳本編程是 Linux 和 Unix 系統管理、自動化任務的核心工具之一。通過 Shell 腳本&#xff0c;你可以自動化重復性操作、簡化復雜流程、提高系統管理效率&#xff0c;甚至構建完整的自動化運維工具。本文將帶你從基礎到進階&#xff0c;全面學習 Shell 腳本編程&…

DelayQueue延遲隊列的使用

1、DelayQueue簡介 DelayQueue 也是 Java 并發包&#xff08;java.util.concurrent&#xff09;中的一個特殊隊列,用于在指定的延遲時間之后處理元素。 DelayQueue的一些關鍵特性&#xff1a; 延遲元素處理&#xff1a;只有當元素的延遲時間到期時&#xff0c;元素才能被取出…

QT6 源,七章對話框與多窗體(6) 顏色對話框 QColorDialog :本類的屬性,信號函數,靜態成員函數,以及源代碼

&#xff08;1&#xff09;本類的繼承關系如下 &#xff1a;&#xff08;2&#xff09; 對于本標準顏色對話框來講&#xff0c;學會使用其靜態函數以獲取到顏色就足夠了。&#xff08;3&#xff09; 開始學習本類的靜態成員函數 &#xff1a;&#xff08;4&#xff09;測試一下…

金倉數據庫:融合進化,智領未來——2025年數據庫技術革命的深度解析

引言 在數字中國戰略的推動下&#xff0c;數據庫作為數字經濟的基礎設施&#xff0c;正經歷著前所未有的技術重構。2025年7月15日&#xff0c;電科金倉以"融合進化&#xff0c;智領未來"為主題&#xff0c;發布了新一代數據庫產品矩陣&#xff0c;標志著國產數據庫在…

【人工智能99問】卷積神經網絡(CNN)的結構和原理是什么?(10/99)

文章目錄卷積神經網絡&#xff08;CNN&#xff09;的結構及原理一、CNN的核心結構1. 輸入層&#xff08;Input Layer&#xff09;2. 卷積層&#xff08;Convolutional Layer&#xff09;2. 卷積層的核心機制&#xff1a;局部感受野與權值共享3. 池化層&#xff08;Pooling Laye…

CCF編程能力等級認證GESP—C++7級—20250628

CCF編程能力等級認證GESP—C7級—20250628單選題&#xff08;每題 2 分&#xff0c;共 30 分&#xff09;判斷題&#xff08;每題 2 分&#xff0c;共 20 分&#xff09;編程題 (每題 25 分&#xff0c;共 50 分)線圖調味平衡單選題&#xff08;每題 2 分&#xff0c;共 30 分&…

《Python 類設計模式:屬性分類(類屬性 VS 實例屬性)與方法類型(實例 / 類 / 靜態)詳解》

Python 類和對象&#xff1a;從 "圖紙" 到 "實物" 的編程思維面向對象編程&#xff08;Object-Oriented Programming&#xff0c;簡稱OOP &#xff09;是一種通過組織對象來編程的方法。1.初識類和對象&#xff1a;用生活例子看透核心概念1.1類-class物與類…

Eureka服務端啟動

目錄 1、相關文章 2、創建eureka-server子工程 3、父工程build.gradle引入版本依賴管理 4、子工程build.gradle引入依賴 5、將main重命名為EurekaApplication并修改代碼 6、添加application.yml文件 7、啟動工程并訪問 8、訪問界面如下 9、 完整目錄結構 1、相關文章 …

AWS Partner: Sales Accreditation (Business)

AWS Partner: Sales Accreditation &#xff08;Business&#xff09;云概念和AWS云計算什么是云計算&#xff1f;計算的演變趨勢云計算部署模型AWS 客戶采用的模式為什么客戶選擇AWSAWS競爭優勢高可用的全球基礎設施AWS服務服務廣度和深度AWS產品和服務服務類別AWS解決方案庫A…

深入理解設計模式之中介者模式:解耦對象交互的利器

為什么需要中介者&#xff1f;在軟件開發中&#xff0c;我們經常會遇到對象之間需要相互通信的場景。當系統規模較小時&#xff0c;對象直接相互引用并通信可能不會帶來太大問題。但隨著系統復雜度增加&#xff0c;對象間的交互關系會變得錯綜復雜&#xff0c;形成一個復雜的網…

從 0 安裝 Label Studio:搭建可后臺運行的數據標注平臺(systemd 實踐

本文將介紹如何使用 pip 安裝 Label Studio&#xff0c;并通過 systemd 實現開機自啟與后臺運行&#xff0c;適用搭建個人項目的數據標注平臺。 一、Label Studio 簡介 Label Studio 是一個開源、跨模態的數據標注工具&#xff0c;支持文本、圖像、音頻、視頻、HTML等多種類型…

【數據結構】鏈表(linked list)

目錄 一、鏈表的介紹 二、單鏈表 1. 單鏈表的初始化 2. 單鏈表的插入 &#xff08;1&#xff09;動態申請一個節點 &#xff08;2&#xff09;頭插法 &#xff08;3&#xff09;尾插法 &#xff08;4&#xff09;按照位置來插入 &#xff08;5&#xff09;在地址之前插…