Kotlin Koans 學習筆記 —— Unit 1

最近在學習 Kotlin 將官方出的練習題做了一遍,將答案以及做題的時候的一些思考記錄於此:

開始

執行:git clone [email protected]:Kotlin/kotlin-koans.git,使用 Idea 打開項目。

1 轉換Java代碼

fun task1(collection: Collection<Int>): String {
    val sb = StringBuilder()
    sb.append("{")
    val iterator = collection.iterator()
    while (iterator.hasNext()) {
        val element = iterator.next()
        sb.append(element)
        if (iterator.hasNext()) {
            sb.append(", ")
        }
    }
    sb.append("}")
    return sb.toString()
}

2 命名參數

fun task2(collection: Collection<Int>): String {
    return collection.joinToString(prefix = "{",postfix = "}")
}

如果之前你瞭解過 Python,很容易理解這一點。在 Kotlin 中,我們可以爲爲參數設置默認值來避免書寫大量重載方法,在使用時,我們可以根據自己的需要按照 參數名 = 參數 這樣的方式填寫需要的參數,使用命名參數時可以忽略參數順序。如果參數中包含沒有使用命名的參數,那這些參數任然遵循方法簽名的順序。

3 默認參數

fun foo(name: String, number: Int = 42, toUpperCase: Boolean = false): String = (if (toUpperCase) name.toUpperCase() else name) + number

fun task3(): String {
    return (foo("a") +
            foo("b", number = 1) +
            foo("c", toUpperCase = true) +
            foo(name = "d", number = 2, toUpperCase = true))
}

4 Lambda 表達式

fun task4(collection: Collection<Int>): Boolean {
    return collection.filter {
        it%2==0
    }.isEmpty().not()
}

過濾函數: filter{(T) -> Boolean}
根據傳入的判斷函數返回一個新的 List 集合

5 字符串模板

fun task5(): String = """\d{2} ${month} \d{4}"""

在 kotlin 中,我們可以在字符串中使用 ${} 來包含一個變量或是一個表達式,如果只是一個變量的情況,可以省略花括號。

6 數據類

data class Person(var name:String,var age :Int)

fun task6(): List<Person> {
    return listOf(Person("Alice", 29), Person("Bob", 31))
}

7 可空類型

要知道 Kotlin 最大的特點就是空安全,除非我們主動生命,不然所有的對象都是不可爲空的。申明一個可空類型的方法十分簡單,只需要在類型聲明後面加上 ?

fun sendMessageToClient(client: Client?, message: String?, mailer: Mailer) {
    client?.personalInfo?.email?.let {email->
        message?.let {
            mailer.sendMessage(email,it)
        }
    }
}

class Client (val personalInfo: PersonalInfo?)
class PersonalInfo (val email: String?)

interface Mailer {
    fun sendMessage(email: String, message: String)
}

使用 ?.let{} 可以讓我們安全的調用可空類型

Kotlin 的幾個標準函數

8 智能轉型

fun eval(e: Expr): Int =
        when (e) {
            is Num -> {
                e.value
            }
            is Sum -> {
               eval( e.left)+ eval(e.right)
            }
        }

when 表達式可以幫助我們智能轉型,當傳入的對象在通過 is xxx 判斷之後,將自動的轉型成這個類型,我們可以直接使用,而無需在顯示轉型。

9 擴展函數

fun Int.r(): RationalNumber = RationalNumber(this,1)
fun Pair<Int, Int>.r(): RationalNumber = RationalNumber(first,second)

擴展函數的聲明與使用都非常簡單,使用 fun 類名.函數名(參數...):返回值 的方式即可聲明一個擴展函數,調用也十分方便,就像調用這個類的自有函數一樣自然。

10 object 表達式

fun task10(): List<Int> {
    val arrayList = arrayListOf(1, 5, 2)
    Collections.sort(arrayList, object :Comparator<Int>{
        override fun compare(o1: Int, o2: Int): Int {
            return o2-o1
        }
    })
    return arrayList
}

在 Java 中我們通常使用 new XXXInterface(){} 來創建一個接口或是抽象類的匿名內部類,但是在 Kotlin 中沒有 new 這個關鍵字,我們可以使用 object 關鍵字來創建一個接口或是抽象類的實現對象。當然,通常的,面對這種僅有一個方法需要實現的接口,我們完全可以使用 Lambda 表達式來書寫,這樣代碼更加簡潔。

11 SAM 轉換

fun task11(): List<Int> {
    val arrayList = arrayListOf(1, 5, 2)
    Collections.sort(arrayList, { x, y ->  y-x })
    return arrayList
}

當一個對象需要實現了一個 SAM(單一抽象方法)接口,你可以使用 Lambda 表達式來代替他。另外,如果一個方法的最後一個參數是一個 SAM 接口,我們可以將 {} 包裹的 Lambda 表達式放到括號外面,效果如下:

Collections.sort(arrayList) { x, y ->  y-x }

12 集合擴展

fun task12(): List<Int> {
    return  arrayListOf(1, 5, 2).sortedDescending()
}

對 List 降序排列,在 kotlin 中只需要調用它的擴展方法即可!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章