Kotlin 中 fold() 和 reduce() 的區別

David Mbochi Njonge 2023年1月30日
  1. Kotlin fold() 方法的作用
  2. Kotlin reduce() 方法實戰
  3. まとめ
Kotlin 中 fold() 和 reduce() 的區別

fold()reduce() 方法是 Iterable 介面的擴充套件函式。這些方法使用元素列表並將它們轉換為單個元素。

由於 Collection 介面實現了 Iterable 介面,因此我們可以將這些方法用於作為 Collection 類的子型別的任何類或介面。

在本教程中,我們將通過了解 fold()reduce() 方法的工作原理併為每種情況提供示例來了解它們之間的區別。

Kotlin fold() 方法的作用

轉到 IntelliJ 並選擇 File > New > Project 建立一個新專案。將專案名稱輸入為 kotlinFoldAndReduce,或任何首選名稱。在 Language 部分選擇 Kotlin,在 Build System 部分選擇 Intellij。按建立按鈕建立專案。

建立專案後,為 fold() 方法建立資料夾結構 com/fold,為 reduce() 方法建立 com/reduce

fold 資料夾下建立一個名為 Main.kt 的新檔案,並將以下程式碼複製並貼上到該檔案中。

package com.fold

class Product(private val name: String,
               private val price: Int){

    fun getName(): String{
        return this.name;
    }

    fun getPrice(): Int{
        return this.price
    }
}

val  products: List<Product> = listOf(
    Product("Hp laptop",200),
    Product("Java book",320),
    Product("Iphone 13",150)
)

fun main() {
    println(products.fold(0) { total, employee ->
       total+employee.getPrice()
    });
}

我們在這段程式碼中建立的 listOf() 輔助方法將返回 Product 元素的列表,從返回的列表中,我們可以呼叫 fold() 方法。

當我們呼叫 fold() 方法時,我們必須提供將用作計算累加器的初始值。請注意,如果返回的集合為空,則 fold() 方法會返回我們提供的初始值。

執行程式碼並驗證它是否輸出列表中所有產品元素的總價格,如下所示。

輸出:

670

fold() 方法也可用於檢查至少大於或小於初始值的值。下面的示例測試列表中的所有 product 元素以返回至少大於 300 的 product 價格,因此我們將 300 設定為 fold() 函式的初始值。

在將此示例複製並貼上到檔案中之前,請確保在 main 方法中註釋掉前面的示例。

fun main() {
    println(products.fold(300) { expensiveProduct, product ->
        if (product.getPrice() > expensiveProduct)
            product.getPrice() else expensiveProduct
    });
}

執行程式碼以驗證它是否輸出以下值:列表中所有 product 元素的最高價格。

輸出:

320

Kotlin reduce() 方法實戰

reduce 資料夾下建立一個 Main.kt 檔案,並將以下程式碼複製並貼上到該檔案中。

package com.reduce

val list: List<Int> = listOf(20,40,60)

fun main() {
    println(list.reduce { sum, value ->
        sum + value
    });
}

由於 reduce() 方法沒有初始值,它使用列表的第一個元素作為初始值。在本例中,值 20 是第一個累加器值,使用 40 的計算返回下一個累加器值。

執行程式碼並確保它輸出以下結果。

輸出:

120

在前面的示例中,我們瞭解到如果列表為空,則返回提供的初始值。reduce() 方法丟擲 UnsupportedOperationExceptionRuntimeException,以防列表為空。

為了防止 reduce() 方法丟擲 RuntimeException,我們可以在進行任何計算之前檢查列表是否為空。如果 int 型別列表為空,則以下程式碼返回值 0

對上一個示例進行註釋,並將此示例複製並貼上到註釋後的檔案中。

package com.reduce

val list: List<Int> = listOf()

fun main() {
    val data = if (list.isEmpty()) 0
    else list.reduce { sum, value ->
        sum + value
    }
    println(data);
}

執行程式碼並注意記錄到控制檯的值是 0,因為我們建立的列表是空的。

輸出:

0

まとめ

在本教程中,我們學習瞭如何區分 fold()reduce() 擴充套件函式。我們還介紹了這兩種方法如何處理列表為空的情況以避免可能引發的異常。

David Mbochi Njonge avatar David Mbochi Njonge avatar

David is a back end developer with a major in computer science. He loves to solve problems using technology, learning new things, and making new friends. David is currently a technical writer who enjoys making hard concepts easier for other developers to understand and his work has been published on multiple sites.

LinkedIn GitHub