每次都有點新收穫

轉載請標明作者與出處:https://www.jianshu.com/p/91c6f28adb31

遍歷集合、控制流、伴生對象

遍歷集合

在 Java 中我們經常需要遍歷一些數組或者集合時我們常用的操作是這樣的:

List<String> list = new ArrayList();
list.add("1");
list.add("2");
list.add("3");
for (String item : list) {
    System.out.println(item);
}
list.forEach((s)-> System.out.println(s)); //Java8中我們可以使用 Lambda 表達式

最常用的應該還是增強 for 循環,在 Kotlin 中我們也可以使用這種增強 for 循環,只是格式不太一樣:

var list:List<String> = listOf("1","2","3","4")
for (item in list) {
    println(item)
}
list.forEach { println(it) }

我們還可以這樣來使用:

for (index in list.indices) {
    println(list[index])
}

調用集合的indices方法可以獲得集合的範圍,上述代碼運行時等同於
“`
for (index in 0..list.lastIndex) {
println(list[index])
}

遍歷一個 Map 以及字符串模板:

![image.png](https://upload-images.jianshu.io/upload_images/2253315-9e0037a2c636759c.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

## 強大的判斷

在第一篇文章中我們曾經提到過,在 Kotlin 中 if-else 不僅僅是判斷語句,他更是一個有返回值的表達式,代碼塊的最後一行的值就是他的返回值。所以,在 Kotlin 中,我們可以寫出這樣的代碼:

override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean {
return if (keyCode == KeyEvent.KEYCODE_BACK && event.action == KeyEvent.ACTION_DOWN) {
if (!acStateIsMap) {
mLlMap.visibility = View.VISIBLE
mLlSearch.visibility = View.GONE
acStateIsMap = true
false
} else {
this.setResult(Activity.RESULT_CANCELED)
finish()
true
}
} else {
super.onKeyDown(keyCode, event)
}
}


在 Kotlin 中還有一個強大的判斷表達式:`when`,這是一個加強版的 if-else 表達式,Kotlin 中推薦我們使用 `when` 來代替 `switch`。如果 when 作爲一個表達式使用,則必須有 else 分支,除非編譯器檢查出我們已經在其中覆蓋了全部的情況。

var result = when (mutablemap.size){
1-> 1
2 ->{
println(“我是一個when中的代碼塊”)
“一共有兩個”
}
3->”3”
else -> println(“大於3個”)
}

可以參考 [Kotlin中when表達式的使用:超強的switch(KAD 13)](https://www.cnblogs.com/figozhg/p/6444312.html)

## 伴生對象與靜態成員
首先我們來看看 Kotlin 中對伴生對象的定義:
> 類內部的對象聲明可以用 companion 關鍵字標記:
>```
>class MyClass {
>    companion object Factory {
>        fun create(): MyClass = MyClass()
>    }
>}
>```
>該伴生對象的成員可通過只使用類名作爲限定符來調用:
>```
>val instance = MyClass.create()
>```
>可以省略伴生對象的名稱,在這種情況下將使用名稱 Companion:
>```
>class MyClass {
>    companion object {
>    }
>}
>val x = MyClass.Companion
>```
>請注意,即使伴生對象的成員看起來像其他語言的**靜態成員**,在運行時他們仍然是**真實對象的實例成員**,而且,例如還可以實現接口:
>```
>interface Factory<T> {
>    fun create(): T
>}
>
>class MyClass {
>    companion object : Factory<MyClass> {
>        override fun create(): MyClass = MyClass()
>    }
>}
>```

簡單解釋就是,伴生對象是與所在類共生的一個對象,請注意這個對象是個天然的單實例:
![伴生對象是天然的單實例](http://upload-images.jianshu.io/upload_images/2253315-293083224a5878d7.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
由於這個特性,我們可以在伴生對象中聲明一個成員,這個成員的實際效果,將等同於在 Java 中創建的一個單例的實例。如果伴生對象沒有命名我們將使用 `類名.Companion` 來訪問,如果命名了則使用 `類名.伴生對象命名` 來訪問,但這不是必須的,通常下是可以省略的。

我們在 Java 中申明一個全局能夠使用的常量時,一般是這樣的:

class Constants{
public static final String SERVER = “xxxxxxxx”;
}

利用伴生對象的屬性特點我們可以這樣聲明一個常量:

class Constants{
companion object {
const val SERVER = “xxxxx”
}
}

在調用時 Java 與 Kotlin 是完全一樣的 :`Constants.SERVER`,注意這裏的 const 修飾符不是必須的,我們聲明成 val 只讀時,他就是一個單例模式的對象中成員變量。加修飾符的話,就是單例模式中的一個靜態成員,根據我們自己的實際情況來決定。

如果我們只是要聲明一個基本類型的靜態常量,完全不用這麼麻煩
在任意 Kotlin 文件的頂層聲明冠以 const 的修飾符即可。

package com.moxigua.smarthome.test

const val SERVER = “XXXXXX”
“`
但是這兩者是不同的,前面我們已經說了,伴生對象是一個單例,所以我們訪問的時候需要先寫上類名,而在頂層的靜態常量則不需要。
訪問時:
image

需要注意的是,這倆者的 import 是不同的,伴生對象調用時,需要導入這個類,而頂層聲明的靜態常量直接導入該常量即可!

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