Kotlin學(xué)習(xí)筆記(一)-語(yǔ)法糖

這篇文章簡(jiǎn)單梳理下Kotlin的語(yǔ)法糖踊跟。

一阁危、內(nèi)置類(lèi)型

1.1 基本類(lèi)型
  • 整數(shù)類(lèi)型:Byte、Short状飞、Int和Long毫胜,Int是默認(rèn)類(lèi)型
  • 浮點(diǎn)類(lèi)型:Float和Double书斜,Double是默認(rèn)類(lèi)型
  • 字符類(lèi)型:Char
  • 布爾類(lèi)型:Boolean
    增加無(wú)符號(hào)類(lèi)型:UByte、UShort酵使、Uint荐吉、ULong

Kotlin數(shù)據(jù)基本類(lèi)型均為對(duì)象類(lèi)型。

Unit 等同于void口渔,Any等同于Object样屠,這是kotlin與java區(qū)別的地方。

  • var 變量
  • val 只讀變量 //作為局部變量等價(jià)于java final常量缺脉,而作為全局變量可以配置get方法痪欲,return值可以不同。
  • const val 全局靜態(tài)常量
類(lèi)型自動(dòng)推導(dǎo)

var b:Int =2 推導(dǎo)為:var a = 2
注:不能直接聲明var a攻礼,要么初始化var a = 2业踢,要么聲明好類(lèi)型var a : Int

強(qiáng)制類(lèi)型轉(zhuǎn)換

var l = 1L
var d = l.toDouble() //這里不像java,類(lèi)型轉(zhuǎn)換必須主動(dòng)調(diào)用toXXX()

字符串比較:

== 比較內(nèi)容 equals
===比較地址 ==

字符串模版

val c = "world"
println("hello $c”)

Raw字符串
val n = """
           <!doctype html>
           <html>
           <head>
               <meta charset="UTF-8"/>
           </head>
           <body>
               <div id="container">
                   <H1>Hello World</H1>
               </div>
           </body>
           </html>
           """.trimIndent()//trim掉公共的空白
別名

typealias ArrayList<E> = java.util.ArrayList<E>

空類(lèi)型安全
操作符 描述
? 可空操作符礁扮,聲明可空類(lèi)型陨亡。 var str:String? = "aaa"
?. 安全調(diào)用操作符,為空返回null深员。str?.length
?.let{} ?.與let一起使用,用于遍歷集合時(shí)蛙埂,則忽略null值倦畅,只對(duì)非空值執(zhí)行操作。
for (item in listWithNulls) {
? ? item?.let { println(it) } // 輸出 abc 并忽略 null
}
?: Elvis操作符,檢查結(jié)果為空返回后面的值绣的。val a = b?.length ?: 0
!! 非空斷言運(yùn)算符叠赐,將任何值轉(zhuǎn)換為非空類(lèi)型,若該值為空則拋出NPE屡江。
as? 嘗試轉(zhuǎn)換成指定類(lèi)型芭概,如果嘗試轉(zhuǎn)換不成功則返回null。var b: Int ? = a as? Int
filterNotNull 過(guò)濾一個(gè)可空類(lèi)型元素集合中的非空元素惩嘉。val list: List<Int> = nullableList.filterNotNull()

另外普調(diào)類(lèi)型與對(duì)應(yīng)的空類(lèi)型的繼承關(guān)系:
String 是String?的子類(lèi)

var x:String = “Hello”
var y:String? = “World”
x = y // 不行罢洲,編譯器報(bào)type mismatch錯(cuò)誤
y = x //可以

String! 為平臺(tái)類(lèi)型,無(wú)法判斷是否為空文黎,需要開(kāi)發(fā)者自己去做安全訪問(wèn)惹苗。

附:看類(lèi)型快捷鍵 shift+control+p

1.2 數(shù)組

IntArray //int[]
Array<Int> //Integer[] 對(duì)象類(lèi)型 Array<Person>

數(shù)組的創(chuàng)建
val c0 = intArrayOf(1, 2, 3, 4, 5) //int[] arr = {1,2,3,4,5}
val c1 = IntArray(5) // int[] arr = new int[5]
val c2 = Array<Int>(5,{it})// 第二個(gè)參數(shù)是方法類(lèi)型, init: (Int) -> T
數(shù)組的遍歷

for each:

for (e in c0) {
   println(e)
}

c0.forEach {
   println(it)
}

for i:

for (i in c0.indices) {
   //i是對(duì)應(yīng)的index
   println(c0[i])
  if(1 in e){// 對(duì)應(yīng)元素是否在數(shù)組中耸峭,!in 對(duì)應(yīng)元素不在數(shù)組中
     println(“1 exists in variable e"])
    }
}
1.3 區(qū)間

區(qū)間

val intRange = 1..10 // [1, 10]
val charRange = 'a'..'z'

開(kāi)區(qū)間

val intRangeExclusive = 1 until 10 // [1, 10)
val charRangeExclusive = 'a' until 'z'

倒序區(qū)間

val intRangeReverse = 10 downTo 1 // [10, 9, ... , 1]
val charRangeReverse = 'z' downTo 'a'

步長(zhǎng)

val intRangeWithStep = 1..10 step 2
val charRangeWithStep = 'a'..'z' step 2
1.4 運(yùn)算符

直接查看官方文檔
https://kotlinlang.org/docs/reference/operator-overloading.html

二桩蓉、 集合

2.1 集合框架

這里一種寫(xiě)法就用java寫(xiě)法就行,區(qū)別就是不用new

var list = ArrayList<String>()
list.add("1")
println(list.get(0))

var map = HashMap<String,String>()
map.put("key","value")
println(map.get("key”))

也可以按標(biāo)準(zhǔn)kotlin寫(xiě)法:

val list = listOf(1, 2, 3)//不可變list(不能添加和刪除元素)
val mutableList = mutableListOf(1, 2, 3)//可變list
val arrays = mutableListOf<Int>()//僅僅初始化劳闹,沒(méi)有元素院究,必須指定泛型類(lèi)型

val map = mapOf( //不可變map
   "a" to 1,
   "b" to 2
)

val mutableMap = mutableMapOf( //可變map
   "a" to 1,
   "b" to 2
)

val maps = mutableMapOf<Int,String>()

list操作:

mutableList.add(4) //set

mutableList.forEach {
   mutableList[2] = 5 //get
   println(it)
}

map操作

mutableMap["c"] = 3//set
mutableMap["c"]//get
mutableMap.set("c", 3)//java式寫(xiě)法set
mutableMap.get("c")//get

同時(shí)注意:
add 操作可用 += 代替, 同理remove 為 -=
例如:mutableList += 4

這里單獨(dú)介紹下循環(huán)

for循環(huán)表達(dá)式

for(item in arrays){//item是每個(gè)元素
   print(item)
}

for(i in arrays.indices){
   print(array[i])
}

while與do..while這部分與java沒(méi)區(qū)別

2.2 集合變換與序列
2.2.1 集合的映射操作:filter洽瞬、map、flatMap
  • filter:保留滿(mǎn)足條件的元素
    list.filter{it %2 == 0}
    變換序列:list.asSequence().filter{it %2 == 0} //.asSequence()類(lèi)似java的 .stream

  • map:集合中的所有元素意義映射新集合
    list.map{it2+1}
    變換序列:list.asSequence().map{it
    2+1}

  • flatMap:集合中的所有元素意義映射新集合业汰,并合并這些集合得到新集合
    list.flatMap{0 until it}.joinToString().let(::println)

.asSequence懶漢式操作案例:

val list = listOf(1, 2, 3, 4)
list.asSequence().filter {
   println("filter:$it")
    it % 2 == 0
}.map {
   println("map:$it")
    it * 2 + 1
}.forEach {
   println("foreach:$it")
}

打印結(jié)果:
filter:1
filter:2
map:2
foreach:5
filter:3
filter:4
map:4
foreach:9

去掉.asSequence對(duì)比:

list.filter {
   println("filter:$it")
    it % 2 == 0
}.map {
   println("map:$it")
    it * 2 + 1
}.forEach {
   println("foreach:$it")
}

打印結(jié)果:
filter:1
filter:2
filter:3
filter:4
map:2
map:4
foreach:5
foreach:9

這部分體會(huì)是有點(diǎn)類(lèi)似于rxjava

2.2.2 集合的聚合操作 sum伙窃、reduce、fold
  • sum 所有元素求和

  • reduce 將元素依次按規(guī)則聚合蔬胯,結(jié)果與元素類(lèi)型一致

  • fold 給定初始化值对供,將元素按規(guī)則聚合,結(jié)果與初始化值類(lèi)型一致
    list.fold(StringBuilder()){
    acc,i->acc.append(i)
    }

三氛濒、表達(dá)式

3.1 if表達(dá)式

kotlin可以把if表達(dá)式的結(jié)果賦值給一個(gè)變量

val max = if (a > b) a else b
3.2 when表達(dá)式

when 將它的參數(shù)和所有的分支條件順序比較产场,直到某個(gè)分支滿(mǎn)足條件。

c = when (x) {
        1 -> print("x等于1")
        in 10..20 -> print(“x在區(qū)間10-20范圍內(nèi)")
        else -> { //default
        }
     }

將條件轉(zhuǎn)移到分支

var x:Any = …
c = when{
        x is String -> c = x.length
        x == 1 -> c = 100
        else -> c = 20
    }

括號(hào)內(nèi)條件還能做賦值

c = when(var input = readLine()){ //since kotlin 1.3
    null -> 0
    else -> input.length
}

循環(huán)中才使用的返回與跳轉(zhuǎn)舞竿,高階函數(shù)forEach不能使用:

  • return京景。默認(rèn)從最直接包圍它的函數(shù)或者匿名函數(shù)返回。
  • break骗奖。終止最直接包圍它的循環(huán)确徙。
  • continue。繼續(xù)下一次最直接包圍它的循環(huán)执桌。
3.3 try…catch表達(dá)式
c = try{
  a/b
}catch(e:Exception){
   e.printStackTrace()
   0
}
3.4 Lambda表達(dá)式

使用:
func()

Lambda表達(dá)式定義:


Kotlin

Lambda表達(dá)式參數(shù)省略

val f1:Function1<Int,Unit> = {p ->     
    println(p)
}

轉(zhuǎn)為:

val f1:Function1<Int,Unit> = {   
    println(it)
}
3.5 SAM轉(zhuǎn)換

一個(gè)參數(shù)類(lèi)型問(wèn)只有一個(gè)方法的Java接口的Java方法調(diào)用時(shí)可用lambda表達(dá)式做轉(zhuǎn)換作為參數(shù)鄙皇。

val eventManager = EventManager()

//匿名內(nèi)部類(lèi):object:類(lèi)型
val onEvent = object:EventManager.OnEventListener{
   override fun onEvent(event:Int){
     println(“onEvent $event") 
   }
}

eventManager.addOnEventListener(onEvent)
eventManager.removeEventListener(onEvent)

四、函數(shù)

kotlin函數(shù)有自己的類(lèi)型仰挣,可以賦值伴逸、傳遞、并在合適的條件下調(diào)用

函數(shù)返回值支持類(lèi)型推導(dǎo)膘壶。

4.1 函數(shù)類(lèi)型:
4.2 函數(shù)的引用
變長(zhǎng)參數(shù):vararg

fun main(vararg args: String) {…}

4.3 多返回值

可以用Pair和Triple進(jìn)行包裝

Pair
val pair = "Hello" to "World"
val pair1 = Pair("Hello", "Kotlin")
val first = pair.first
val second = pair.second
val (x, y) = pair

Triple

val triple = Triple("a", 1, 1.0)
val first = triple.first
val second = triple.second
val third = triple.third
val (x, y, z) = triple

比如:

fun multiReturn():Triple<Int,Long,String>{
   return Triple(1,3L,"aaa")
}

fun main() {
    val (i, l, s) = multiReturn()
    println(i+l)
}

默認(rèn)參數(shù)和具名參數(shù)

fun defaultParameter(x: Int = 5, y: String, z: Long = 0L){...}
fun main() {
   defaultParameter(y = "aaa")
}
4.4 高階函數(shù)

參數(shù)類(lèi)型包含函數(shù)類(lèi)型或返回值類(lèi)型為函數(shù)類(lèi)型的函數(shù)為高階函數(shù)

public inline fun <R> IntArray.map(transform: (Int) -> R): List<R> {//參數(shù)類(lèi)型包含函數(shù)類(lèi)型(Int) -> R错蝴,返回值類(lèi)型包含函數(shù)類(lèi)型List<R>
    return mapTo(ArrayList<R>(size), transform)
}

函數(shù)類(lèi)型為最后一個(gè)參數(shù)可以移到括號(hào)外面,且省略小括號(hào):

intArray.forEach{ it -> Unit
    println(it)
}

省略為:

intArray.forEach { print(it) }

intArray.forEach { print(it) } 又等價(jià)于  intArray.forEach(::print)   //::print 匹配類(lèi)型為(Int) -> Unit的函數(shù)引用颓芭,可直接傳入

完整案例:

fun cost(block: () -> Unit) {
    val start = System.currentTimeMillis()
    block()
    print("cost:${System.currentTimeMillis() - start}")
}

fun fibonacci(): () -> Long {
    var first = 0L
   var second = 1L
   return {
       val next = first + second
        val current = first
        first = second
        second = next
        current //return current
   }
}

fun main(args: Array<String>) {
    cost {
       val fib = fibonacci()
        for (i in 0..10) {
            print(fib())
        }
    }
}
4.5 內(nèi)聯(lián)函數(shù) inline

函數(shù)體內(nèi)的多個(gè)函數(shù)執(zhí)行優(yōu)化為一個(gè)函數(shù)體來(lái)執(zhí)行顷锰,提升代碼執(zhí)行性能。常用于高階函數(shù)亡问,將參數(shù)函數(shù)和自身方法體合和一個(gè)函數(shù)體來(lái)執(zhí)行官紫。

inline fun cost(block: () -> Unit) {
    val start = System.currentTimeMillis()
    block()
    print("cost:${System.currentTimeMillis() - start}")
}
內(nèi)聯(lián)高階函數(shù)的return
val ints = intArrayOf(1, 2, 3, 4)

ints.forEach {
   if (it == 3) return@forEach //僅僅跳出這一次內(nèi)聯(lián)函數(shù)的調(diào)用相當(dāng)于continue,continue只能用在循環(huán)中
   print(it)
}
non-local return
ints.forEach {
   if (it == 3) return //直接退出
   print(it)
}

禁止non-local return :關(guān)鍵字 crossinline

inline fun Runnable(crossinline block:()->Unit):Runnable{ //也可以使用no inline block:()->Unit,禁止函數(shù)內(nèi)聯(lián)州藕,這樣前面的inline就沒(méi)有意義了万矾。
  return object : Runnable{
     override fun run(){
         block()
      }
   }
}

內(nèi)聯(lián)函數(shù)的限制

  • public/protected 的內(nèi)聯(lián)方法只能訪問(wèn)對(duì)應(yīng)類(lèi)的public成員
  • 內(nèi)聯(lián)函數(shù)的內(nèi)聯(lián)函數(shù)參數(shù)不能被存儲(chǔ)(賦值給變量)
  • 內(nèi)聯(lián)函數(shù)的內(nèi)聯(lián)函數(shù)參數(shù)只能傳遞給其他內(nèi)聯(lián)函數(shù)參數(shù)

簡(jiǎn)而言之:

  • public 只能訪問(wèn)public
  • 內(nèi)聯(lián)只能訪問(wèn)內(nèi)聯(lián)
  • 參數(shù)不能被存
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請(qǐng)通過(guò)簡(jiǎn)信或評(píng)論聯(lián)系作者慎框。
  • 序言:七十年代末良狈,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子笨枯,更是在濱河造成了極大的恐慌薪丁,老刑警劉巖遇西,帶你破解...
    沈念sama閱讀 218,682評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異严嗜,居然都是意外死亡粱檀,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,277評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)漫玄,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)茄蚯,“玉大人,你說(shuō)我怎么就攤上這事睦优∩#” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,083評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵汗盘,是天一觀的道長(zhǎng)皱碘。 經(jīng)常有香客問(wèn)我,道長(zhǎng)隐孽,這世上最難降的妖魔是什么癌椿? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,763評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮菱阵,結(jié)果婚禮上踢俄,老公的妹妹穿的比我還像新娘。我一直安慰自己晴及,他們只是感情好褪贵,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,785評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著抗俄,像睡著了一般。 火紅的嫁衣襯著肌膚如雪世舰。 梳的紋絲不亂的頭發(fā)上动雹,一...
    開(kāi)封第一講書(shū)人閱讀 51,624評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音跟压,去河邊找鬼胰蝠。 笑死,一個(gè)胖子當(dāng)著我的面吹牛震蒋,可吹牛的內(nèi)容都是我干的茸塞。 我是一名探鬼主播,決...
    沈念sama閱讀 40,358評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼查剖,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼钾虐!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起笋庄,我...
    開(kāi)封第一講書(shū)人閱讀 39,261評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤效扫,失蹤者是張志新(化名)和其女友劉穎倔监,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體菌仁,經(jīng)...
    沈念sama閱讀 45,722評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡浩习,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了济丘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片谱秽。...
    茶點(diǎn)故事閱讀 40,030評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖摹迷,靈堂內(nèi)的尸體忽然破棺而出疟赊,到底是詐尸還是另有隱情,我是刑警寧澤泪掀,帶...
    沈念sama閱讀 35,737評(píng)論 5 346
  • 正文 年R本政府宣布听绳,位于F島的核電站,受9級(jí)特大地震影響异赫,放射性物質(zhì)發(fā)生泄漏椅挣。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,360評(píng)論 3 330
  • 文/蒙蒙 一塔拳、第九天 我趴在偏房一處隱蔽的房頂上張望鼠证。 院中可真熱鬧,春花似錦靠抑、人聲如沸量九。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,941評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)荠列。三九已至,卻和暖如春载城,著一層夾襖步出監(jiān)牢的瞬間肌似,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,057評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工诉瓦, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留川队,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,237評(píng)論 3 371
  • 正文 我出身青樓睬澡,卻偏偏與公主長(zhǎng)得像固额,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子煞聪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,976評(píng)論 2 355

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