kotlin 練習

kotlin基礎語法

96 
samychen 
2017.05.28 17:07* 字數 1224 閱讀 2434評論 0

每種編程語言都有必定的語法、語義和執行順序(同步),學習一種新語言也都是從這三者出發,下面咱們就只針對kotlin的語法來作簡單的介紹。javascript

Kotlin有本身的特性不應被Java的思惟所束縛。php

  1. 基本語法準則:
    在Kotlin中常量用 val 聲明,變量用 var 聲明;
    關鍵字在前面,類型以冒號 :隔開在後面,也能夠省略直接賦值;
    類型後帶問號 ? 表示可爲空類型(默認空類型安全);
    常量 val 延遲加載 by lazy{} ;
    默認是線程安全的,關閉線程安全 lazy(LazyThreadSafetyMode.NONE){} ;
    變量 var 延遲加載 lateinit ;
    內部類和參數默認爲public,而在Java中爲private
    類默認爲不可繼承(final),想要可被繼承要聲明爲 open 或 abstract
    取消了static關鍵字,靜態方法和參數統一寫在 companion object 塊
    internal模塊內可見,inner內部類
//常量數組int[][][] arrs = new int[3][2][1]; val arrs = Array(3) { Array(2) { IntArray(1) } } internal var name: String? = null//類型後帶問號 ? 表示可爲空類型(默認空安全) internal var age: Int = 0//internal模塊內可見,inner內部類 //當咱們只有單個構造器時,咱們須要在從父類繼承下來的構造器中指定須要的參數。這是用來替換Java中的super調用的。 open class Animal(name: String) class Person(name: String, surname: String) : Animal(name) 

kotlin是空類型安全的,全部變量默認爲"not null",必須顯式在類型後添加?修飾符纔可賦值爲null。html

var notNullArtist: Artist = null//編譯不經過,由於notNullArtist不能爲null var artist: Artist? = null//編譯經過 artist.print()//編譯不經過,由於artist可能爲空 /** Kotlin進行空判斷處理,有兩種處理方式: * 1. 拋出空異常,字段後加 !! * 2. 不作處理直接跳過,字段後加 ? */ artist?.print()//編譯經過,作了非空判斷,只有當artist!=null時才調用print() artist!!.print()//這種用法只有在確認artist不爲null時才能調用,不然拋出空指針異常 val name = artist?.name?:"empty"//當artist爲null時能夠指定一個默認值 
  1. 條件語句
    if...else 正常使用,不過移除了 switch 用更強大的 when 替代,when子式能夠是各類返回Boolean的表達式
val x = 7
when (x) {
  in 1..5 -> print("x is in the range") in validNumbers -> print("x is valid") !in 10..20 -> print("x is outside the range") else -> print("none of the above") } 

kotlin儘量多的使用whenjava

  1. 循環語句
    while 和 do...while 同Java並沒有區別, for 則有很大改變並多出了幾個變種
fun main(args: Array<String>) { var list = ArrayList<String>() add(list) list.forEachIndexed { i, s -> print(list[i]) print(s) } println() //若是沒有指定函數的返回值,它就會返回Unit,與Java中的void相似,可是Unit是一個真正的對象。固然也能夠指定任何其它的返回類型: list.forEachIndexed(object :(Int,String) -> Unit{ override fun invoke(i: Int, s: String) { print(list[i]) print(s) } }) } //遞增for (int i = 0; i < list.size(); i++) for (i in list.indices) { print(list[i]) } //遞增for (int i = 2; i < list.size(); i++) for (i in 2..list.size-1) { print(list[i]) } //遞減for (int i = list.size(); i >= 0; i--) for (i in list.size downTo 0) { print(list[i]) } //操做列表內的對象 for (item in list) { print(item) } //增強版 for((i,item) in list.withIndex()){ print(list[i]) print(item) } //變種版 list.forEach { print(it) } list.forEachIndexed { i, s -> print(list[i]) print(s) } list.forEachIndexed(object :(Int,String) -> Unit{ override fun invoke(i: Int, s: String) { print(list[i]) print(s) } }) fun add(list:MutableList<String>) { for (i in 0..4) { list.add(i.toString() + "") } } 

冒號使用
  在Kotlin中冒號 : 用萬能來稱呼毫不爲過。常量變量的類型聲明,函數的返回值,類的繼承都須要它android

除此以外還有一個特別的地方也須要它,使用Java類的時候。Kotlin最終會仍是編譯成Java字節碼,使用到Java類是必然的,在Kotlin語法以下
val intent = Intent(this, MainActivity::class.java)git

指定上下文的@編程

除了冒號另外一個重要符號 @ ,java代碼中常常用到內部類和匿名內部類,有時咱們不能肯定this指代的上下文,Java可使用XXX.this指代具體上下文,在kotlin中的作法是this@XXX數組

class User { inner class State{ fun getUser(): User{ //返回User return this@User } fun getState(): State{ //返回State return this@State } } } 

kotlin的特點

Java的 getter/setter 方法自動轉換成屬性,對應到Kotlin屬性的調用安全

public class User { private String name; private String age; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } } 

對應的kotlinbash

val user = User()
//賦值 user.name = "tutu" user.age = "23" //取值 val name = user.name val age = user.age class User { var name: String? = null var age: String? = null } 

有時 getter/setter 方法比較複雜,這就須要自定義 getter/setter 了,實現一個Java中經常使用的單例,這裏只爲了展現,單例在Kotlin有更簡單的方法實現,只要在 package 級別建立一個 object 便可

class User { companion object {//靜態方法和參數統一寫在 companion object 塊 //volatile不保證原子操做,因此,很容易讀到髒數據。在兩個或者更多的線程訪問的成員變量上使用volatile @Volatile var instance: User? = null get() { if (field == null) { synchronized(User::class.java) { if (field == null) field = User() } } return field } } var name: String? = null var age: String? = null } 

自定義 getter/setter 重點在 field ,跟咱們熟悉所Java的 this 指代當前類同樣, field 指代當前參數,直接使用參數名 instance 代替不會報錯但單例就沒效果了

字符串問題

在Java中拼接字符串的代碼可讀性都不好,在Kotlin字符串拼接變得很是簡潔,只需用 $ 後面加上參數名,複雜的參數要加上 {}

val pair = Pair(1, "one") val (num, name) = pair println("num = $num, name = $name") 

輸出num = 1, name = one

Java8新特性lambda的支持

lambda須要一個函數,可是又不想費神去命名一個函數的場合下使用,也就是指匿名函數。使用功能接口,把接口名、方法名和參數類型省掉不寫再加個 -> 罷了。

使用Java開發Android時,處理監聽回調是常見的事,kotlin能夠直接編寫監聽回調而不用再經過匿名對象傳遞onClick方法,這個特性被稱爲Lambda表達式

view.setOnclickListener({
      Toast.makeText(this, "Hello World!", Toast.LENGTH_LONG).show() }) 

擴展函數

能夠爲任何已經存在的類添加新函數,相比傳統工具類,擴展函數更具備可讀性。

//爲Fragment添加擴展函數 fun Fragment.toast(message: CharSequence, duration: Int = Toast.LENGTH_LONG){ Toast.makeText(getActivity(), message, duration).show() } 

調用時直接調用fragment.toast("Hello World!")或fragment.toast("Hello World!", 2000)

Kotlin中的參數與Java中有些不一樣。如你所見,咱們先寫參數的名字再寫它的類型。上面調用的第二個參數(length)指定了一個默認值。這意味着你調用的時候能夠傳入第二個值或者不傳,這樣能夠避免你須要的重載函數。

函數式支持(lambda),函數是一級公民

集合操做

  list轉map(associateBy)

  場景:訂單列表轉換成以 id爲key 的訂單map

val mainOrders = orderDao!!.queryUserOrder(param)
val orderMap = mainOrders.associateBy { it.id }.toMap()

  map的key或者value轉換

  假如一個map的key是String,須要轉換成Long;或者map的value是一個對象,要轉成另外一個對象。按照標準Java寫法,能夠要new一個新的map,而後循環老的map,在kotlin中,一行代碼搞定

val map = mutableMapOf(1 to 1, 2 to 2)
val newMap = map.mapKeys { "key_${it.key}" }.mapValues { "value_${it.value}" } println(newMap) //打印結果 {key_1=value_1, key_2=value_2} val pair = Pair("ss","sg") val map = mapOf(pair) val map1=map.mapKeys { entry -> "${entry.value}!" } for((key,value) in map1){ println("map1:key=$key") println("map1:value=$value") } val map2 =map.mapKeys { (key, value) -> "$value" } for((key,value) in map2){ println("map2:key=$key") println("map2:value=$value") } val map3=map.mapValues { entry -> "${entry.value}!" } for((key,value) in map3){ println("map3:key=$key") println("map3:value=$value") } val map4=map.mapValues { (key, value) -> "$value" } for((key,value) in map4){ println("map4:key=$key") println("map4:value=$value") } 打印結果: map1:key=sg! map1:value=sg map2:key=sg map2:value=sg map3:key=ss map3:value=sg! map4:key=ss map4:value=sg 

參考文獻
  Kotlin for android Developers
  kotlin 腳本練習

相關文章
相關標籤/搜索