kotlin 常見 關(guān)鍵詞

1药蜻、 componentX (多聲明)

val f1 = Forecast(Date(), 27.5f, "Shinny")
val (date, temperature, details) = f1
//=======================
// 上面的多聲明會被編譯成下面的代碼
val date = f1.component1()
val temperature = f1.component2()
val details = f1.copmponent3()
// 映射對象的每一個屬性到一個變量中结蟋,這就是 多聲明阁危。
// object class 默認(rèn)具有該屬性。但普通 class 想要具有這種屬性俭缓,需要這樣做:
class person(val name: String, val age: Int) {
    operator fun component1(): String {
        return name
    }
    operator fun component2(): Int {
        return age
    }
}

val 必須有: 用來保存在 component1 和 component2 中返回構(gòu)造函數(shù)傳進(jìn)來的參數(shù)的聋溜。
operator 暫時還不明真相,IDE 提示的。 操作符重載脯倒,函數(shù)名為操作符名(即系統(tǒng)默認(rèn)的關(guān)鍵詞实辑,此處為 component1,component2).當(dāng)使用該操作時,自己重寫的操作會覆蓋系統(tǒng)默認(rèn)的操作藻丢。

// 常見用法:該特性功能強(qiáng)大剪撬,可以極大的簡化代碼量。 如 map 中的擴(kuò)展函數(shù)實(shí)現(xiàn)悠反,允許在迭代時使用 key value
for ((key, value) in map) {
    Log.d("map","key:$key, value:$value")
}

2残黑、 Companion objects (伴生對象)

類似于 java 中的 靜態(tài)屬性或方法,可以表示一個類中的靜態(tài)屬性斋否、常量梨水、函數(shù)。

3茵臭、with function

 > 包含在 kotlin 的標(biāo)準(zhǔn)函數(shù)庫中疫诽。接收一個對象和一個擴(kuò)展函數(shù)作為它的參數(shù),然后使這個對象擴(kuò)展這個函數(shù)笼恰。表示所有在括號中編寫的代碼都是作為對象(第一個參數(shù))的一個擴(kuò)展函數(shù)踊沸,可以就像 this 一樣使用所有它的 public 方法和屬性。當(dāng)針對同一個對象做很多操作時非常有利于簡化代碼社证。

4逼龟、 operator 操作符重載

  > Kotlin 有一些固定數(shù)量象征性的操作符,可以在任何類中很容易地使用追葡。方法是創(chuàng)建一個方法腺律,方法名為保留的操作符關(guān)鍵字,這樣就可以讓這個操作符的行為映射到這個方法宜肉。
一元操作符
操作符 函數(shù)
+a a.unaryPlus()
-a a.unaryMinus()
!a a.not()
a++ a.inc()
a-- a.dec()
二元操作符
操作符 函數(shù)
a + b a.plus(b)
a - b a.minus(b)
a * b a.times(b)
a / b a.div(b)
a % b a.mod(b)
a..b a.rangeTo(b)
a in b a.contains(b)
a !In b !a.contains(b)
a += b a.plusAssign(b)
a -= b a.minusAssign(b)
a *= b a.timesAssign(b)
a /= b a.divAssign(b)
a %= b a.modAssign(b)
數(shù)組操作符
操作符 函數(shù)
a[i] a.get(i)
a[i,j] a.get(i,j)
a[i_1,...,i_n] a.get(i_1,...,i_n)
a[i] = b a.set(i,b)
a[i,j] = b a.set(i,j,b)
a[i_1,...,i_n] = b a.set(i_1,...,i_n,b)
等于操作符
操作符 函數(shù)
a == b a?.equals(b)?:b === null
a != b !(a?.equals(b)?: b === null)
函數(shù)調(diào)用操作符
操作符 函數(shù)
a(i) a.invoke(i)
a(i,j) a.invoke(i,j)
a(i_1,...,i_n) a.invoke(i_1,...,i_n)

3匀钧、 lambda

函數(shù)里定義 lambda 表達(dá)式形參

 fun setOnClickListener(listener: (View) -> Unit)
 // 表達(dá)式通過參數(shù)的形式被定義在箭頭的左邊(被圓括號包圍),然后在箭頭的右邊返回結(jié)果谬返。該例中之斯,接收一個 View, 返回 Unit

調(diào)用

view.setOnClickListener({ toast("clicked")})
// 當(dāng)定義了一個方法,必須使用大括號包圍遣铝,然后在箭頭的左邊指定參數(shù)佑刷,在箭頭的右邊返回函數(shù)執(zhí)行的結(jié)果。如果左邊的參數(shù)沒有使用到酿炸,可以省略左邊的參數(shù):
view.setOnClickListener({ toast("clicked")})
//如果這個函數(shù)的最后一個參數(shù)是一個函數(shù)瘫絮,可以把這個函數(shù)移動到圓括號外:
view.setOnClickListener() { toast("clicked")}
// 最后,如果這個函數(shù)只有一個參數(shù)填硕,可以省略這個圓括號
view.setOnClickListener { toast("clicked")}

4麦萤、 inline (內(nèi)聯(lián)函數(shù))

內(nèi)聯(lián)函數(shù)與普通的函數(shù)有點(diǎn)不同。一個內(nèi)聯(lián)函數(shù)會在編譯的時候被替換掉,而不是真正的方法調(diào)用壮莹。這在譯寫情況下可以減少內(nèi)存分配和運(yùn)行時開銷翅帜。例如,有一函數(shù)只接收一個函數(shù)作為它的參數(shù)垛孔。如果是普通函數(shù)藕甩,內(nèi)部會創(chuàng)建一個含有那個函數(shù)的對象。而內(nèi)聯(lián)函數(shù)會把我們調(diào)用這個函數(shù)的地方替換掉周荐,所以它不需要為此生成一個內(nèi)部的對象。

 // 例一僵娃、創(chuàng)建代碼塊只提供 Lollipop 或更高版本來執(zhí)行
inline fun supportsLollipop(code: () -> Unit) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        code()
    }
}
// usage
supportsLollipop {
    window.setStatusBarColor(Color.BLACK)
}

5概作、可見性修飾符

  1、private
  2默怨、protected:一個包成員不能被定義為 protected.
  3讯榕、internal:如果一個定義為  internal 的包成員的話,對所在的整個 module 可見匙睹。如果它是一個其他領(lǐng)域的成員愚屁,它就需要依賴那個領(lǐng)域的可見性。如有一個 private 類痕檬,那么它的 internal 修飾的函數(shù)的可見性會限制與它所在的該類的可見性霎槐。可以訪問同一個 module 中的 internal 修飾的類梦谜,但不能訪問其他 module的丘跌。
  4、public: 僅受限于它的領(lǐng)域唁桩。一個定義為 public 的成員被包含在一個 privaet 修飾的勒種闭树,這個成員在這個類之外也是不可見的。

6荒澡、構(gòu)造器

  所有構(gòu)造器默認(rèn)都是 public 的报辱,它們類是可見的,可以被其他地方使用单山。也可以使用該語法把構(gòu)造函數(shù)修改為 private:
  class C private constructor(a: Int) {...}

7碍现、Kotlin for Android Extensions

7.1、Activities / Fragments 的 Android Extensions
  import kotlinx.android.synthetic.activity_main.*
  // 在 setContentView 被調(diào)用后就可以通過 id 名來訪問 XML 中定義的 View
  import kotlinx.android.synthetic.activity_main.*
  // 可以通過 include 標(biāo)簽在 activity 默認(rèn)布局中增加內(nèi)嵌的布局饥侵。
7.2鸵赫、Views Android Extensions
  import kotlinx.android.synthetic.view_item.view.*
  // 綁定一個 xml 中的 view 到另外一個 view。

8躏升、Application 單例化和屬性的 Delegated (by)

  class App : Application() {
      companion object {
          private var instance: Application? = null
          fun  instance() = instance!!
      }
      override fun onCreate() {
          super.onCreate()
          instance = this
      }
  }

我們可能需要一個屬性具有一些相同的行為辩棒,使用 lazy 或 observable 可以被很有趣的實(shí)現(xiàn)重用,而不是一次又一次的去聲明那些相同的代碼。kotlin 提供了一個委托屬性到一個類的方法一睁。這就是委托屬性

 class Delegate<T> : ReadWriteProperty<Any?, T> {
      fun getValue(thisRef: Any?, property: KProperty<*>): T {
            return ...
      }
      fun setValue(thisRef: Any?,property: KProperty<*>, value: T) {...}  
      // 如果該屬性是不可修改(val), 就會只有一個 getValue 函數(shù)
  }
8.1钻弄、lazy
  1、包含一個 lambda者吁,當(dāng)?shù)谝淮螆?zhí)行 getValue 時該 lambda 會被調(diào)用窘俺,所以該屬性可以被延遲初始化。之后的調(diào)用都只會返回同一個值复凳。
  2瘤泪、lazy 操作符是線程安全的。  
  3育八、如果不擔(dān)心多線程問題或想提高更多的性能对途,可以使用 lazy(LazyThreadSafeMode.NONE) { ... }
  4、一般 lazy 委托的代碼塊可以阻止在多個不同的線程中創(chuàng)建多個對象髓棋。
class App : Application() {
   val database: SQLiteOpenHelper by lazy {
       MyDatabaseHelper(applicationContext)
    }
    override fun onCreate() {
      super.onCreate()
      val db = database.writeableDatabase
    }
}
8.2实檀、Observable
  1、該委托可以檢測希望觀察的屬性變化按声。當(dāng)被觀察屬性的 set 方法被調(diào)用時膳犹,它就會自動執(zhí)行我們指定的 lambda 表達(dá)式。所以一旦該屬性被賦予了新值签则,則可以收到被委托的屬性须床、舊值和新值。
class ViewModel(val db: MyDatabase) {
  var myProperty by Delegates.observable("") {
    d,old,new ->
    db.saveChanges(this,new)
  }
}
8.3怀愧、Vetoable
1侨颈、一個特殊的 observable, 可以來決定是否保存這個值。在真正保存之前進(jìn)行一些條件判斷芯义。
var positiveNumber = Delegates.vetoable(0) {
    d, old, new -> 
    new >= 0
}
// 上面這個委托只允許在新的值是正數(shù)時執(zhí)行保存哈垢。在 lambda 中,最后一行表示返回值扛拨。不需要使用 return 關(guān)鍵字(實(shí)質(zhì)上不能被編譯)
8.4耘分、Not Null
  1、場景1:需要在某些地方初始化該屬性绑警,但不能在構(gòu)造函數(shù)中確定求泰,或不能在構(gòu)造函數(shù)中做任何事。
  2计盒、場景2:在 Activity fragment service receivers...中渴频,一個非抽象的屬性在構(gòu)造函數(shù)執(zhí)行之前需要被賦值。
   3北启、解決方案1:使用可 null 類型并且賦值為 null卜朗,直到真正去賦值拔第。氮素,在使用時就需要不停的進(jìn)行 not null 判斷场钉。
   4蚊俺、解決方案2:使用 notnull 委托。含有一個可 null 的變量并會在設(shè)置該屬性時分配一個真實(shí)的值逛万。如果該值在被獲取之前沒有被分配泳猬,它就會拋出一個異常。
class App : Application() {
  companion object {
    var instance: App by Delegates.notnull()
  }
   override fun onCreate() {
      super.onCreate()
      instance = this
    }
}
8.5宇植、從 Map 中映射值
  另一種委托方式得封,屬性的值會從一個map中獲取 value,屬性的名字對應(yīng)這個map 中的 key当纱。
import kotlin.properties.getValue
class Configuration(map: Map<String,Any?>) {
  val width: Int by map
  val height: Int by map
  val dp: Int by map
  val deviceName: String by map
}
// usage
conf = Configuration(mapof(
  "width" to 1080,
  "height" to 720,
  "dp" to 240,
   "deviceName" to "myDecive"
))
8.6 custom delegate
 自定義委托需要實(shí)現(xiàn) ReadOonlyProperty / ReadWriteProperty 兩個類呛每,具體取決于被委托的對象是 val 還是 var
// step1
private class NotNullSingleValueVar<T>() : ReadWriteProperty<Any?, T> {
  private var value: T? = null
  override fun getValue(thisRef: Any?, property: KProperty<*>): T {
      return value ?: throw IllegalStateException("${desc.name not initialized}")
  }
  
  override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
      this.value = if (this.value == null) value else throw IllegalStateException("${desc.name} already initialized")
      }
}
// step2: usage
object DelegatesExt {
  fun notNullSingleValue<T>(): ReadWriteProperty<Any?, T> = NotNullSingleValueVar()
}
8.7 重新實(shí)現(xiàn) Application 單例
class App : Application() {
    companion object {
        var instance: App by Delegates.notNull()
    }

    override fun onCreate() {
        super.onCreate()
        instance = this
    }
}  
// 此時可以在 app 的任何地方修改這個值,因?yàn)?*如果使用 Delegates.notNull(), 屬性必須是 var 的坡氯。可以使用剛剛創(chuàng)建的委托洋腮,只能修改該值一次
companion object {
    var instance: App by DeleagesExt.notNullSingleValue()
}

9箫柳、集合和函數(shù)操作

  1、Iterable: 父類啥供∶趸校可以遍歷一系列的都是實(shí)現(xiàn)這個接口
  2、MutableIterable: 一個支持便利的同時可以執(zhí)行刪除的 Iterables
  3伙狐、Collection:
  4涮毫、MutableCollection:支持增加刪除item 的 collection。提供了額外的函數(shù)贷屎,如 add罢防、remove、clear等
  5唉侄、List: 范性有序集合咒吐。
  6、MutableList: 支持增刪item 的 List
  7属划、Set: 無序并不支持重復(fù) item 的 集合
  8恬叹、MutableSet: 支持增刪item 的 Set
  9、 Map: 
  10同眯、MutableMap: 支持增刪 item 的 map
9.1绽昼、總數(shù)操作符

1、Any:如果至少有一個元素符合給出的判斷條件须蜗,則返回 true

val list = listOf(1,2,3,4,5,6)
assertTrue(list.any { it % 2 == 0 })
assertFalse(list.any { it > 10})

2硅确、all:如果全部的元素符合給出的判斷條件目溉,則返回 true

assertTrue(list.add { it < 10})
assertFalse(list.all { it % 2 == 0})

3、count: 返回符合給出判斷條件的元素總數(shù)

assertEquals(3,list.count {it % 2 == 0})

4疏魏、fold: 在一個初始值的基礎(chǔ)上從第一項(xiàng)到最后一項(xiàng)通過一個函數(shù)累計所有的元素

asserEquals(25, list.fold(4) { total, next -> total + next})

5停做、foldRight: 與 fold 一樣,但順序是從最后一項(xiàng)到第一項(xiàng)大莫。
6蛉腌、forEach: 遍歷所有元素,并執(zhí)行給定的操作只厘。

list.forEach { println(it) }

7烙丛、forEachIndexed: 與 forEach ,同時可得到元素的 Index

list.forEachIndexed { index, value -> println("position $index contains a $value")}

8羔味、max: 返回最大一項(xiàng)河咽,如果沒有則返回 null
9、maxBy: 根據(jù)給定的函數(shù)返回最大的一項(xiàng)赋元,沒有返回 null

assertEquals(1, list.maxBy { -it })

10忘蟹、min
11、minBy
12搁凸、none
13媚值、reduce:與fold一樣,但沒有初始值护糖。通過一個函數(shù)從第一項(xiàng)到最后一項(xiàng)進(jìn)行累計褥芒。

assertEquals(21, list.reduce {total, next -> total + next})

14、reduceRight: 順序從最后一項(xiàng)到第一項(xiàng)
15嫡良、sumBy: 返回所有每一項(xiàng)通過函數(shù)轉(zhuǎn)換之后的數(shù)據(jù)的總和锰扶。

9.2、過濾操作符

1寝受、drop:返回包含去掉前 n 個元素的所有元素的列表

assertEquals(listOf(5,6), list.drop(4))

2坷牛、dropWhile: 返回根據(jù)給定函數(shù)從第一項(xiàng)開始去掉指定元素的列表
3、dropLastWhile:返回根據(jù)給定函數(shù)從最后一項(xiàng)開始去掉指定元素的列表
4羡蛾、filter:過濾

assertEquals(listOf(2,4,6), list.filter{it % 2 == 0})

5漓帅、filterNot
6、filterNotNull
7痴怨、slice:過濾一個list 中指定 index 的元素
8忙干、take: 返回從第一個開始的 n 個元素
9、takeLast: 返回從最后一個開始的 n 個元素
10浪藻、takeWhile: 返回從第一個開始符合給定函數(shù)條件的元素

9.3捐迫、映射操作符

1、flatMap:遍歷所有的元素爱葵,為每一個創(chuàng)建一個集合施戴,最后把所有集合放在一個集合中反浓。
2、groupBy:返回一個根據(jù)給定函數(shù)分組后的 map
3赞哗、map:返回一個每一個元素根據(jù)給定函數(shù)轉(zhuǎn)換所組成的list
4雷则、mapIndexed:返回一個每一個元素根據(jù)給定的包含元素 index 的函數(shù)轉(zhuǎn)換所組成的 list
5、mapNotNull

9.4肪笋、元素操作符

1月劈、contains
2、elementAt:返回給定index對應(yīng)的元素藤乙,如果index數(shù)組越界則會拋出 IndexOutOfBoundsException
3猜揪、elementAtOrElse: 越界則給出默認(rèn)值
4、elementAtOrNull
5坛梁、first
6而姐、firstOrNull
7、indexOf
8划咐、indexofFirst
9拴念、indexOfLast
10、last
11褐缠、lastIndexOf
12丈莺、lastOrNull
13、single:返回符合給定函數(shù)的單個元素送丰,如果沒有符合或超過一個,則拋出異常
14弛秋、singleOrNull

9.5器躏、生產(chǎn)操作符

1、merge:把兩個集合合并為一個新的蟹略,相同index的元素通過給定的函數(shù)進(jìn)行合并生成新的元素作為新集合中的一個元素登失,返回新集合。新集合的大小由最小的那個集合大小決定
2挖炬、partition: 把一個給定集合的分割為兩個揽浙,第一個集合是由原集合每一項(xiàng)元素匹配給定函數(shù)條件返回 true 的元素組成,第二集合為false
3意敛、plus
4馅巷、zip:返回由 pair 組成的 list,每個 pair 由 兩個集合中相同index 的元素組成。該返回的 list 大小由最小的那個集合決定草姻。
5钓猬、unzip:從包含 pair 的 List 中生成包含List的Pair

9.6、順序操作符

1撩独、reverse:返回一個與指定list相反順序的list
2敞曹、sort:返回一個自然排序后的list
3账月、sortBy:指定函數(shù)排序
4、sortDescending:降序
5澳迫、sortDescendingBy:指定函數(shù)降序

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末局齿,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子橄登,更是在濱河造成了極大的恐慌抓歼,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件示绊,死亡現(xiàn)場離奇詭異锭部,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)面褐,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進(jìn)店門拌禾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人展哭,你說我怎么就攤上這事湃窍。” “怎么了匪傍?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵您市,是天一觀的道長。 經(jīng)常有香客問我役衡,道長缘滥,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任搞旭,我火速辦了婚禮雄嚣,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘棵介。我一直安慰自己钉鸯,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布邮辽。 她就那樣靜靜地躺著唠雕,像睡著了一般。 火紅的嫁衣襯著肌膚如雪吨述。 梳的紋絲不亂的頭發(fā)上岩睁,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天,我揣著相機(jī)與錄音锐极,去河邊找鬼笙僚。 笑死,一個胖子當(dāng)著我的面吹牛灵再,可吹牛的內(nèi)容都是我干的肋层。 我是一名探鬼主播亿笤,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼栋猖!你這毒婦竟也來了净薛?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤蒲拉,失蹤者是張志新(化名)和其女友劉穎肃拜,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體雌团,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡燃领,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了锦援。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片猛蔽。...
    茶點(diǎn)故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖灵寺,靈堂內(nèi)的尸體忽然破棺而出曼库,到底是詐尸還是另有隱情,我是刑警寧澤略板,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布毁枯,位于F島的核電站,受9級特大地震影響叮称,放射性物質(zhì)發(fā)生泄漏种玛。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一瓤檐、第九天 我趴在偏房一處隱蔽的房頂上張望蒂誉。 院中可真熱鬧,春花似錦距帅、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至悄窃,卻和暖如春讥电,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背轧抗。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工恩敌, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人横媚。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓纠炮,卻偏偏與公主長得像月趟,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子恢口,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內(nèi)容