常熟網(wǎng)站開發(fā)搜索大全引擎入口
以下內(nèi)容摘自郭霖《第一行代碼》第三版
文章目錄
- Kotlin變量
- Kotlin循環(huán)語句
- Kotlin條件語句
- Kotlin繼承
- Kotlin主構造函數(shù)與次構造函數(shù)
- Kotlin實現(xiàn)
- Kotlin函數(shù)的可見性修飾符
- Kotlin data關鍵字
- Kotlin單例模式
- Kotlin List集合
- Kotlin Set集合
- Kotlin Map映射
- Kotlin Lamda表達式
- Kotlin any和all函數(shù)
- Kotlin線程
- Kotlin空指針問題
- Kotlin判空輔助工具
- let函數(shù)
- Kotlin字符串內(nèi)嵌表達式
- Kotlin函數(shù)的參數(shù)設置
Kotlin變量
- val 表示不可變變量,類似于Java中用final關鍵字修飾的變量
- var表示可變變量
Kotlin循環(huán)語句
… 左閉右閉
until 左閉右開
downTo 倒序左閉右閉
step 代表每次遞增的數(shù)字
ps:主要用于for循環(huán)和while循環(huán)等
Kotlin條件語句
Kotlin中條件語句用when關鍵詞
fun getScore(name: String) = when(name){"Tom" -> 86"Jim" -> 77"Jack" -> 95"Lily" -> 100else -> 0 // 相當于switch-case語句里面的default
}fun getScore2(name: String) = when{name.startsWith("Tom") -> 86name == "Jim" -> 77name == "Jack" -> 95name == "Lily" -> 100else -> 0 // 相當于switch-case語句里面的default
}fun checkNumber(num: Number){when(num){is Int -> println("number is Int")is Double -> println("number is Double")is Float -> println("number is Float")else -> println("number is not support")}
}
Kotlin繼承
在Kotlin中任何一個非抽象類默認都是不可以被繼承的
:用來表示繼承關系,而且需要被繼承的類在關鍵字class前面加上open
open class Person(){var name = ""var age = 0
}
class Student: Person(){var sno = ""var grade = 0
}
Kotlin主構造函數(shù)與次構造函數(shù)
- 主構造函數(shù)只能有一個,次構造函數(shù)可以有多個
- 次構造函數(shù)通過constructor關鍵字來定義
- Kotlin中允許可以只有次構造函數(shù),沒有主構造函數(shù)
class Student: Person{constructor(name: String, age: Int): super(name, age){}
}
Kotlin實現(xiàn)
使用,來表示實現(xiàn)關系,并且不需要加括號
允許對接口中定義的函數(shù)進行默認實現(xiàn)
interface Study {fun readBooks()fun doHomework(){println("do homework default implementation.")}
}
Kotlin函數(shù)的可見性修飾符
Java中是private、protected、public和default(默認項)
Kotlin中是private(同Java)、protected(只對當前類和子類可見)、public(默認項,同Java)和internal(比如我們開發(fā)了一個模塊給別人使用,但是有一些函數(shù)只允許在模塊內(nèi)部調(diào)用,不想暴露給外部,就可以將這些函數(shù)聲明成internal)
修飾符 | Java | Kotlin |
---|---|---|
public | 所有類可見 | 所有類可見(默認) |
protected | 當前類、子類、同一包路徑下的類可見 | 當前類、子類可見 |
private | 當前類可見 | 當前類可見 |
default | 同一包路徑下的類可見(默認) | 無 |
internal | 無 | 同一模塊中的類可見 |
Kotlin data關鍵字
當在一個類前面聲明了data關鍵字時,就表明你希望這個類是一個數(shù)據(jù)類,Kotlin會根據(jù)主構造函數(shù)中的參數(shù)幫你將equals()、hashCode()、toString()等固定且無實際邏輯意義的方法自動生成。
Kotlin單例模式
直接將class關鍵字改為object關鍵字
object Singleton {fun singletonTest(){println("singletonTest is called.")}
}
調(diào)用單例類中的函數(shù)比較類似于Java中靜態(tài)方法的調(diào)用方式:
Singleton.singletonTest()
Kotlin List集合
// listOf表示不可變的集合,即該集合只可讀
val list = listOf("apple", "banana", "orange", "pear", "Grape")
for(fruit in list){println(fruit)
}
// 獲取單詞長度最大的那個
println("The max length of list is " + list.maxBy { it.length })// mutableListOf表示可變的集合
val list1 = mutableListOf("apple", "banana", "orange", "pear", "Grape")
list1.add("watermelon")
for(fruit in list1){println(fruit)
}
Kotlin Set集合
val set = setOf("apple", "banana", "orange", "pear", "Grape", "banana")
for(fruit in set){println(fruit)
}val set1 = mutableSetOf("apple", "banana", "orange", "pear", "Grape", "banana")
set1.add("watermelon")
set1.add("orange")
for(fruit in set1){println(fruit)
}
Kotlin Map映射
val map = HashMap<String, Int>()
map.put("Apple", 1)
map.put("banana", 2)
map.put("orange", 3)
map.put("pear", 4)
map.put("grape", 5)val number = map.get("Apple")// 不建議使用上述get()和put()方法,建議使用以下方法
map["Apple"] = 1
map["banana"] = 2
map["orange"] = 3
map["pear"] = 4
map["grape"] = 5val number = map["Apple"]// 但是還有更簡單的方法
val map = mapOf("Apple" to 1, "Banana" to 2, "Orange" to 3, "Pear" to 4, "Grape" to 5)
// 遍歷
for((fruit, number) in map){println("fruit is " + fruit + ", number is " + number)
}
Kotlin Lamda表達式
語法結(jié)構:
{參數(shù)名1: 參數(shù)類型, 參數(shù)名2: 參數(shù)類型 -> 函數(shù)體}
首先最外層是一對大括號,如果有參數(shù)傳入到Lambda表達式中的話,我們還需要聲明參數(shù)列表,參數(shù)列表的結(jié)尾使用一個->符號,表示參數(shù)列表的結(jié)束以及函數(shù)體的開始,函數(shù)體中可以編寫任意行代碼(雖然不建議編寫太長的代碼),并且最后一行代碼會自動作為Lambda表達式的返回值。
val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape")
val lambda = {fruit: String -> fruit.length}
val maxLengthFruit = list.maxBy(lambda)
println("The max length of list is " + maxLengthFruit)// 進行簡化
val maxLengthFruit = list.maxBy({fruit: String -> fruit.length})
// Kotlin規(guī)定,當Lambda參數(shù)是函數(shù)的最后一個參數(shù)時,可以將Lambda表達式移到函數(shù)括號的外面
val maxLengthFruit = list.maxBy(){fruit: String -> fruit.length}
// 如果Lambda參數(shù)是函數(shù)的唯一一個參數(shù)的話,還可以將函數(shù)的括號省略
val maxLengthFruit = list.maxBy{fruit: String -> fruit.length}
// 由于Kotlin擁有出色的類型推導機制,Lambda表達式中的參數(shù)列表其實在大多數(shù)情況下不必聲明參數(shù)類型
val maxLengthFruit = list.maxBy{fruit -> fruit.length}
// 當Lambda表達式的參數(shù)列表中只有一個參數(shù)時,也不必聲明參數(shù)名,而是可以使用it關鍵字來代替
val maxLengthFruit = list.maxBy { it.length }
filter函數(shù)是用來過濾集合中的數(shù)據(jù)的,它可以單獨使用,也可以配合剛才的map函數(shù)一起使用。
fun main() {val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")val newList = list.filter { it.length <= 5 }.map { it.toUpperCase() }for (fruit in newList) {println(fruit)}
}
Kotlin any和all函數(shù)
any函數(shù)用于判斷集合中是否至少存在一個元素滿足指定條件,all函數(shù)用于判斷集合中是否所有元素都滿足指定條件。
val list = listOf("Apple", "Banana", "Orange", "Pear", "Grape", "Watermelon")
var anyResult = list.any { it.length <= 5 }
var allResult = list.all { it.length <= 5 }
// anyResult = true, allResult = false
println("anyResult = " + anyResult + ", allResult = " + allResult)
Kotlin線程
Thread(object: Runnable{override fun run() {println("Thread is running...")}
}).start()// 對代碼進行精簡
Thread(Runnable { println("Thread is running...")
}).start()// 再精簡
Thread({ println("Thread is running...")
}).start()// 繼續(xù)精簡
Thread{ println("Thread is running...")
}.start()
Kotlin空指針問題
Kotlin默認所有的參數(shù)和變量都不可為空,Kotlin將空指針異常的檢查提前到了編譯時期
可為空的類型:在類名的后面加上一個問號。Int表示不可為空的整型,而Int?就表示可為空的整型;String表示不可為空的字符串,而String?就表示可為空的字符串
Kotlin判空輔助工具
?.操作符。當對象不為空時正常調(diào)用相應的方法,當對象為空時則什么都不做。
if (a != null) {a.doSomething()
}// 直接替換為
a?.doSomething()
?:操作符。這個操作符的左右兩邊都接收一個表達式,如果左邊表達式的結(jié)果不為空就返回左邊表達式的結(jié)果,否則就返回右邊表達式的結(jié)果。
var a: Int = 10
var b: Int = 20val c = if(a != null){a
}else{b
}// 直接替換為
val c1 = a ?: b
想要強行通過編譯,使用非空斷言,在對象后面加上!!。這是一種有風險的寫法意在告訴Kotlin,我非常確信這里的對象不會為空,所以不用你來幫我做空指針檢查了,如果出現(xiàn)問題,你可以直接拋出空指針異常,后果由我自己承擔。(有風險)
var content: String? = "hello"
fun main() {if (content != null) {printUpperCase()}
}
fun printUpperCase() {val upperCase = content.toUpperCase()println(upperCase)
}
這個代碼是無法通過編譯的,需要改成以下代碼:
fun printUpperCase() {val upperCase = content!!.toUpperCase()println(upperCase)
}
let函數(shù)
// 本來我們進行一次if判斷就能隨意調(diào)用study對象的任何方法,但受制于?.操作符的限制,現(xiàn)在變成了每次調(diào)用study對象的方法時都要進行一次if判斷
fun doStudy(study: Study?){if(study != null){study.doHomework()}if(study != null){study.readBooks()}
}// 結(jié)合使用?.操作符和let函數(shù)來對代碼進行優(yōu)化
fun doStudy1(study: Study?){study?.let { stu ->stu.doHomework()stu.readBooks()}
}// 當Lambda表達式的參數(shù)列表中只有一個參數(shù)時,可以不用聲明參數(shù)名,直接使用it關鍵字來代替即可
fun doStudy3(study: Study?){study?.let { it.doHomework()it.readBooks()}
}
let函數(shù)是可以處理全局變量的判空問題的,而if判斷語句則無法做到這一點
Kotlin字符串內(nèi)嵌表達式
val name = "Annie"
val str = "hello, $name. Nice to meet you!"
Kotlin函數(shù)的參數(shù)設置
可以通過鍵值對的方式來傳參,從而不必像傳統(tǒng)寫法那樣按照參數(shù)定義的順序來傳參
fun printParams(num: Int = 100, str: String) {println("num is $num , str is $str")
}
fun main() {printParams(str = "world")
}
當次構造函數(shù)的作用是提供使用更少參數(shù)來對類進行實例化的方式時,我們完全可以通過只編寫一個主構造函數(shù),然后給參數(shù)設定默認值的方式來實現(xiàn)。