Kotlin 語法基礎(chǔ)大全,從例子著手的 從0到1的學(xué)習(xí) -- 基礎(chǔ)介紹
Kotlin 語法基礎(chǔ)大全沈矿,從例子著手的 從0到1的學(xué)習(xí) -- 流程控制
Kotlin 語法基礎(chǔ)大全惦辛,從例子著手的 從0到1的學(xué)習(xí) -- 特殊的類
Kotlin 語法基礎(chǔ)大全,從例子著手的 從0到1的學(xué)習(xí) -- 函數(shù)
Kotlin 語法基礎(chǔ)大全悦穿,從例子著手的 從0到1的學(xué)習(xí) -- 集合
Kotlin 語法基礎(chǔ)大全攻礼,從例子著手的 從0到1的學(xué)習(xí) -- 作用域
Kotlin 語法基礎(chǔ)大全,從例子著手的 從0到1的學(xué)習(xí) -- 代理
Kotlin 語法基礎(chǔ)大全咧党,從例子著手的 從0到1的學(xué)習(xí) -- 產(chǎn)品級特性
翻譯來源
List
list 是一個有序的集合秘蛔。在kotlin中 list 可以是可變的 MutableList
也可以是只讀的 List
。在創(chuàng)建list的時候傍衡,使用標(biāo)準(zhǔn)類庫里的 listOf()
創(chuàng)建只讀的不可變的 List
深员,使用 mutableListOf()
創(chuàng)建可變的list。為了避免不必要的修改蛙埂,你可以用List的引用來指向可變list倦畅, 這將避免錯誤的修改。
val systemUsers: MutableList<Int> = mutableListOf(1, 2, 3) // 1
val sudoers: List<Int> = systemUsers // 2
fun addSudoer(newUser: Int) { // 3
systemUsers.add(newUser)
}
fun getSysSudoers(): List<Int> { // 4
return sudoers
}
fun main() {
addSudoer(4) // 5
println("Tot sudoers: ${getSysSudoers().size}") // 6
getSysSudoers().forEach { // 7
i -> println("Some useful info on user $i")
}
// getSysSudoers().add(5) <- Error! // 8
}
- 1 創(chuàng)建一個可變的list
- 2 通過一個
List
的對象來指向 可變list绣的。這將避免對List
進行修改 - 3 定義一個方法叠赐,將一個int 值添加到 可變list
- 4 定義一個方法欲账,來獲取可變list的一個 不可變引用。
- 5 調(diào)用
addSudoer
方法 - 6 獲取不可變list 引用 然后讀取size
- 7 獲取不可變list 引用再循環(huán)遍歷
- 8 獲取不可變list 然后調(diào)用add 方法將會導(dǎo)致報錯
Set
set 是一種無序的集合芭概,并且不存在重復(fù)的健值赛不。創(chuàng)建set,可以使用setOf()
和 mutableSetOf()
罢洲。和list 一樣踢故,set 可以通過一個不可變的引用來避免不必要的修改。
val openIssues: MutableSet<String> = mutableSetOf("uniqueDescr1", "uniqueDescr2", "uniqueDescr3") // 1
fun addIssue(uniqueDesc: String): Boolean {
return openIssues.add(uniqueDesc) // 2
}
fun getStatusLog(isAdded: Boolean): String {
return if (isAdded) "registered correctly." else "marked as duplicate and rejected." // 3
}
fun main() {
val aNewIssue: String = "uniqueDescr4"
val anIssueAlreadyIn: String = "uniqueDescr2"
println("Issue $aNewIssue ${getStatusLog(addIssue(aNewIssue))}") // 4
println("Issue $anIssueAlreadyIn ${getStatusLog(addIssue(anIssueAlreadyIn))}") // 5
}
- 1 創(chuàng)建一個可變的set
- 2 定義一個方法往可變set里面添加元素惹苗,set的add 將會返回添加是否成功的結(jié)果
- 3 定義一個方法
- 4 打印添加成功的結(jié)果
- 5 打印添加失敗的結(jié)果
Map
map 是一個鍵值對的集合殿较,鍵是唯一的,并且是用來找到相關(guān)的value值的桩蓉。創(chuàng)建 map 同樣有兩種方法mapOf
和 mutableMapOf
淋纲。使用to
的中綴方法可以快速的創(chuàng)建map 。和list 一樣院究,map 可以通過一個不可變的引用來避免不必要的修改洽瞬。
const val POINTS_X_PASS: Int = 15
val EZPassAccounts: MutableMap<Int, Int> = mutableMapOf(1 to 100, 2 to 100, 3 to 100) // 1
val EZPassReport: Map<Int, Int> = EZPassAccounts // 2
fun updatePointsCredit(accountId: Int) {
if (EZPassAccounts.containsKey(accountId)) { // 3
println("Updating $accountId...")
EZPassAccounts[accountId] = EZPassAccounts.getValue(accountId) + POINTS_X_PASS // 4
} else {
println("Error: Trying to update a non-existing account (id: $accountId)")
}
}
fun accountsReport() {
println("EZ-Pass report:")
EZPassReport.forEach { // 5
k, v -> println("ID $k: credit $v")
}
}
fun main() {
accountsReport() // 6
updatePointsCredit(1) // 7
updatePointsCredit(1)
updatePointsCredit(5) // 8
accountsReport() // 9
}
- 1 創(chuàng)建一個可變的map ,并且展示了 to的用法
- 2 創(chuàng)建一個不可變的引用
- 3 檢查key是否已經(jīng)存在
- 4 讀取key相對應(yīng)的value 儡首,并且將其修改
- 5 遍歷不可變map 和輸出他的鍵值對
- 6 在修改之前片任,先打印出結(jié)果
- 7 修改兩次存在的key的對應(yīng)的value
- 8 修改不存在的key對應(yīng)的value
- 9 再打印一遍結(jié)果
filter
過濾方法可以允許你對集合進行過濾,filter 需要你提供一個lambda的參數(shù)蔬胯,lambda函數(shù)將會對每一個元素進行判斷对供,如果判斷的是true,那么久將結(jié)果加入到返回的集合中去氛濒。
fun main() {
val numbers = listOf(1, -2, 3, -4, 5, -6) // 1
val positives = numbers.filter { x -> x > 0 } // 2
val negatives = numbers.filter { it < 0 } // 3
println("Numbers: $numbers")
println("Positive Numbers: $positives")
println("Negative Numbers: $negatives")
}
/*
Numbers: [1, -2, 3, -4, 5, -6]
Positive Numbers: [1, 3, 5]
Negative Numbers: [-2, -4, -6]
*/
- 1 創(chuàng)建一個list
- 2 過濾保留大于0的元素
- 3 過濾保留小于0的元素
map
map 這個擴展方法假褪,可以讓你對集合中的每個元素做一個轉(zhuǎn)化梅屉,你需要的是傳入一個lambda的函數(shù)陷寝,作為轉(zhuǎn)化所必須的元素奉芦。
fun main() {
val numbers = listOf(1, -2, 3, -4, 5, -6) // 1
val doubled = numbers.map { x -> x * 2 } // 2
val tripled = numbers.map { it * 3 } // 3
println("Numbers: $numbers")
println("Doubled Numbers: $doubled")
println("Tripled Numbers: $tripled")
}
/*
Numbers: [1, -2, 3, -4, 5, -6]
Doubled Numbers: [2, -4, 6, -8, 10, -12]
Tripled Numbers: [3, -6, 9, -12, 15, -18]
*/
- 1 創(chuàng)建一個list
- 2 所有元素都 * 2
- 3 所有元素都 * 3,這里可以便捷的使用it骗奖,因為這里可以進行類型推斷
any, all, none
這幾個方法用于檢查集合中的方法是否符合給出的條件
any
any 方法當(dāng)集合中至少有一個符合給出的條件就返回true
fun main() {
val numbers = listOf(1, -2, 3, -4, 5, -6) // 1
val anyNegative = numbers.any { it < 0 } // 2
val anyGT6 = numbers.any { it > 6 } // 3
println("Numbers: $numbers")
println("Is there any number less than 0: $anyNegative")
println("Is there any number greater than 6: $anyGT6")
/*
Numbers: [1, -2, 3, -4, 5, -6]
Is there any number less than 0: true
Is there any number greater than 6: false
*/
}
- 1 定義一個list
- 2 是否有一個元素小于0
- 3 是否有一個元素大于6
all
當(dāng)集合中所有的元素都符合條件的時候返回true
fun main() {
val numbers = listOf(1, -2, 3, -4, 5, -6) // 1
val allEven = numbers.all { it % 2 == 0 } // 2
val allLess6 = numbers.all { it < 6 } // 3
println("Numbers: $numbers")
println("All numbers are even: $allEven")
println("All numbers are less than 6: $allLess6")
/*
Numbers: [1, -2, 3, -4, 5, -6]
All numbers are even: false
All numbers are less than 6: true
*/
}
- 1 定義一個數(shù)組
- 2 判斷是否所有元素都是偶數(shù)
- 3 判斷是否所有元素都小于6
none
當(dāng)沒有一個元素是符合給出的條件的是否返回true
fun main() {
val numbers = listOf(1, -2, 3, -4, 5, -6) // 1
val allEven = numbers.none { it % 2 == 1 } // 2
val allLess6 = numbers.none { it > 6 } // 3
println("Numbers: $numbers")
println("All numbers are even: $allEven")
println("No element greater than 6: $allLess6")
/*
Numbers: [1, -2, 3, -4, 5, -6]
All numbers are even: false
No element greater than 6: true
*/
}
- 1 定義一個list
- 2 檢查是否沒有元素是奇數(shù)
- 3 檢查是否沒有元素都是大于6
find, findLast
查找集合中符和條件的第一個元素或者最后一個元素确徙,如果查找不到就返回null。
fun main() {
val words = listOf("Lets", "find", "something", "in", "collection", "somehow") // 1
val first = words.find { it.startsWith("some") } // 2
val last = words.findLast { it.startsWith("some") } // 3
val nothing = words.find { it.contains("nothing") } // 4
println("The first word starting with \"some\" is \"$first\"")
println("The last word starting with \"some\" is \"$last\"")
println("The first word containing \"nothing\" is ${nothing?.let { "\"$it\"" } ?: "null"}")
}
/*
The first word starting with "some" is "something"
The last word starting with "some" is "somehow"
The first word containing "nothing" is null
*/
- 1 創(chuàng)建一個list
- 2 查找以some開頭的第一個元素
- 3 察州以some開頭的最后一個元素
- 4 查找包含noting的第一個元素
first, last
first, last
返回相應(yīng)的集合的第一個或者最后一個元素执桌。你可以傳入lambda表達式作為條件來篩選 第一個或者最后一個元素鄙皇。這個方法會是一種斷言的方法,如果集合為空仰挣,或者不包含符和條件的元素將會拋出 NoSuchElementException
fun main() {
val numbers = listOf(1, -2, 3, -4, 5, -6) // 1
val first = numbers.first() // 2
val last = numbers.last() // 3
val firstEven = numbers.first { it % 2 == 0 } // 4
val lastOdd = numbers.last { it % 2 != 0 } // 5
println("Numbers: $numbers")
println("First $first, last $last, first even $firstEven, last odd $lastOdd")
}
- 1 創(chuàng)建一個list
- 2 讀取list的第一個元素
- 3 讀取list的最后一個元素
- 4 讀取第一個符和條件的元素伴逸,及第一個偶數(shù)
- 5 讀取最后一個符和條件的元素,及最后一個奇數(shù)
firstOrNull, lastOrNull
這些方法與上面兩個方法不同在于膘壶,如果沒有符和條件的元素错蝴,將會返回null
fun main() {
val words = listOf("foo", "bar", "baz", "faz") // 1
val empty = emptyList<String>() // 2
val first = empty.firstOrNull() // 3
val last = empty.lastOrNull() // 4
val firstF = words.firstOrNull { it.startsWith('f') } // 5
val firstZ = words.firstOrNull { it.startsWith('z') } // 6
val lastF = words.lastOrNull { it.endsWith('f') } // 7
val lastZ = words.lastOrNull { it.endsWith('z') } // 8
println("First $first, last $last")
println("First starts with 'f' is $firstF, last starts with 'z' is $firstZ")
println("First ends with 'f' is $lastF, last ends with 'z' is $lastZ")
}
- 1 定義一個list
- 2 定義一個空list
- 3 讀取空list的第一個元素洲愤,這里返回null,不會報錯
- 4 讀取空list的最后一個元素顷锰,這里返回null柬赐,不會報錯
- 5 查找符和條件的第一個元素,結(jié)果是foo
- 6 查找符和條件的第一個元素馍惹,結(jié)果是null
- 7 查找符和條件的最后一個元素躺率,結(jié)果是null
- 8 查找符和條件的最后一個元素,結(jié)果是faz
count
count 方法將會返回集合的元素個數(shù)万矾,或者返回符和條件的集合的元素個數(shù)
fun main() {
val numbers = listOf(1, -2, 3, -4, 5, -6) // 1
val totalCount = numbers.count() // 2
val evenCount = numbers.count { it % 2 == 0 } // 3
println("Total number of elements: $totalCount")
println("Number of even elements: $evenCount")
}
- 1 定義一個llist
- 2 計算數(shù)量
- 3 計算符和條件的數(shù)量,這里是計算所有偶數(shù)的數(shù)量
associateBy, groupBy
兩個方法都用于從一個集合中通過對key 進行歸類然后來創(chuàng)建一個map慎框。key 可以通過使用keySelector參數(shù)來選擇良狈,你也可以通過valueSelector 來進行value的選擇。
兩者之間的區(qū)別
- associateBy:value 會使用符和條件的最后一個元素
- groupBy:會把所有符和條件的元素作為放到一個數(shù)組中 作為value
返回的map中的entry的順序維持了原來的list的順序笨枯。
fun main() {
data class Person(val name: String, val city: String, val phone: String) // 1
val people = listOf( // 2
Person("John", "Boston", "+1-888-123456"),
Person("Sarah", "Munich", "+49-777-789123"),
Person("Svyatoslav", "Saint-Petersburg", "+7-999-456789"),
Person("Vasilisa", "Saint-Petersburg", "+7-999-123456"))
val phoneBook = people.associateBy { it.phone } // 3
val cityBook = people.associateBy(Person::phone, Person::city) // 4
val peopleCities = people.groupBy(Person::city, Person::name) // 5
println("People: $people")
println("Phone book: $phoneBook")
println("City book: $cityBook")
println("People living in each city: $peopleCities")
}
/*
People: [Person(name=John, city=Boston, phone=+1-888-123456), Person(name=Sarah, city=Munich, phone=+49-777-789123), Person(name=Svyatoslav, city=Saint-Petersburg, phone=+7-999-456789), Person(name=Vasilisa, city=Saint-Petersburg, phone=+7-999-123456)]
Phone book: {+1-888-123456=Person(name=John, city=Boston, phone=+1-888-123456), +49-777-789123=Person(name=Sarah, city=Munich, phone=+49-777-789123), +7-999-456789=Person(name=Svyatoslav, city=Saint-Petersburg, phone=+7-999-456789), +7-999-123456=Person(name=Vasilisa, city=Saint-Petersburg, phone=+7-999-123456)}
City book: {+1-888-123456=Boston, +49-777-789123=Munich, +7-999-456789=Saint-Petersburg, +7-999-123456=Saint-Petersburg}
People living in each city: {Boston=[John], Munich=[Sarah], Saint-Petersburg=[Svyatoslav, Vasilisa]}
*/
- 1 定義一個data class
- 2 定義一個people的list
- 3 構(gòu)建一個map薪丁,這個map的key是 people的的phone, value沒有寫馅精,就默認(rèn)為自身严嗜。
- 4 構(gòu)建一個map,key為people的phone洲敢,value 為people的city
- 5 構(gòu)建一個map漫玄,key為city,value為city相同的所有people的name
partition
用于將一個list分為兩個部分压彭,
fun main() {
val numbers = listOf(1, -2, 3, -4, 5, -6) // 1
val evenOdd = numbers.partition { it % 2 == 0 } // 2
val (positives, negatives) = numbers.partition { it > 0 } // 3
println("Numbers: $numbers")
println("Even numbers: ${evenOdd.first}")
println("Odd numbers: ${evenOdd.second}")
println("Positive numbers: $positives")
println("Negative numbers: $negatives")
}
flatMap
用于遍歷集合中的每個元素睦优,然后將所有的結(jié)果放置到一個單獨的數(shù)組中去。轉(zhuǎn)化方式由用戶定義壮不。
fun main() {
val numbers1 = listOf("1", "2", "3") // 1
val numbers = listOf(1, 2, 3)
val tripled = numbers.flatMap { listOf(it, it, it) } // 2
val tripled1 = numbers1.flatMap { listOf(it, it + 1) }
println("Numbers: $numbers1")
println("Transformed: $tripled1")
println("Numbers: $numbers")
println("Transformed: $tripled")
}
- 1 定義一個數(shù)字的數(shù)組
- 2 關(guān)鍵點在于返回的結(jié)果不是一個list的list 而是一個list 有九個元素
min, max
選出集合中最大和最小的元素汗盘,其中如果集合為空,則返回null
fun main() {
val numbers = listOf(1, 2, 3)
val empty = emptyList<Int>()
val numbers1 = listOf("1", "2", "3")
println("Numbers: $numbers, min = ${numbers.min()} max = ${numbers.max()}") // 1
println("Empty: $empty, min = ${empty.min()}, max = ${empty.max()}") // 2
println("Numbers: $numbers1, min = ${numbers1.min()} max = ${numbers1.max()}") // 3
}
/*
Numbers: [1, 2, 3], min = 1 max = 3
Empty: [], min = null, max = null
*/
sorted
返回一個集合的list 根據(jù)他們的自然排列順序(升序)
sortedBy 根據(jù)某個規(guī)則按照升序的方式排列
import kotlin.math.abs
fun main() {
val shuffled = listOf(5, 4, 2, 1, 3, -10) // 1
val natural = shuffled.sorted() // 2
val inverted = shuffled.sortedBy { -it } // 3
val descending = shuffled.sortedDescending() // 4
val descendingBy = shuffled.sortedByDescending { abs(it) } // 5
println("Shuffled: $shuffled")
println("Natural order: $natural")
println("Inverted natural order: $inverted")
println("Inverted natural order by absolute value: $descending")
println("Inverted natural order of absolute values: $descendingBy")
}
- 1 創(chuàng)建一個list
- 2 排序询一,按照自然關(guān)系排序
- 3 按照自然關(guān)系倒序排序
- 4 按照自然關(guān)系倒序排序隐孽,通過使用sortedDescending
- 5 按照自然關(guān)系倒序排序,通過將每個元素進行取絕對值運算
Map Element Access map元素的訪問
kotlin 通過 []
來獲取value根據(jù)key值健蕊,如果獲取不到就返回null菱阵。getvalue()
方法也可以獲取當(dāng)前的value,只不過如果獲取不到value绊诲,將會throw exception送粱。我們可以通過withDefault
創(chuàng)建一個新的map,在這個map中掂之,getvalue()
將不會拋出異常抗俄,取而代之地是將會返回默認(rèn)值
fun main(args: Array<String>) {
val map = mapOf("key" to 42)
val value1 = map["key"] // 1
val value2 = map["key2"] // 2
val value3: Int = map.getValue("key") // 1
val mapWithDefault = map.withDefault { k -> k.length }
val value4 = mapWithDefault.getValue("key2") // 3
try {
map.getValue("anotherKey") // 4
} catch (e: NoSuchElementException) {
println("Message: $e")
}
println("value1 is $value1")
println("value2 is $value2")
println("value3 is $value3")
println("value4 is $value4")
}
- 1 返回42
- 2 返回null
- 3 返回4脆丁,value 是計算出來地动雹,按照代碼是根據(jù)key地長度 計算出來地槽卫。
- 4 報錯,anotherKey 不在map中
zip
將兩個集合合并成一個新的集合胰蝠,默認(rèn)的合成方式為歼培,結(jié)果集中包含的是兩個集合的元素按照index 兩兩組成一個pair,當(dāng)然你可以按照直接的方式來組成新的數(shù)據(jù)結(jié)構(gòu)茸塞。
結(jié)果集的大小是由兩個源數(shù)據(jù)的長度的最小值來決定的
fun main() {
val A = listOf("a", "b", "c") // 1
val B = listOf(1, 2, 3, 4) // 1
val resultPairs = A zip B // 2
val resultReduce = A.zip(B) { a, b -> "$a$b" } // 3
println("A to B: $resultPairs")
println("\$A\$B: $resultReduce")
}
/*
A to B: [(a, 1), (b, 2), (c, 3)]
$A$B: [a1, b2, c3]
*/
- 1 定義了兩個list
- 2 將兩個list 合并成一個pair的list躲庄。zip 作為一個中綴方法在這里使用
- 3 將兩個list合并成一個list,按照給出的方式合并钾虐,在這里噪窘,兩個參數(shù)將被合并成為一個string。結(jié)果集也就是一個stirng的list
getOrElse
這個方法提供了一種安全的方式去訪問list效扫,不用再擔(dān)心數(shù)組越界的問題倔监,如果訪問的不是數(shù)組內(nèi)的index,你可以提供一個默認(rèn)的值以返回菌仁。
fun main() {
val list = listOf(0, 10, 20)
println(list.getOrElse(1) { 42 }) // 1
println(list.getOrElse(10) { 42 }) // 2
}
/*
10
42
*/
- 1 打印了第二個元素 10
- 2 第11個元素明顯越界了浩习,返回了提供的默認(rèn)值 42
getOrElse還可以用在map上。
fun main() {
val map = mutableMapOf<String, Int?>()
println(map.getOrElse("x") { 1 }) // 1
map["x"] = 3
println(map.getOrElse("x") { 1 }) // 2
map["x"] = null
println(map.getOrElse("x") { 1 }) // 3
}
/*
1
3
1
*/
- 1 打印了默認(rèn)值1 因為x 不在key的范圍內(nèi)
- 2 打印了 3 因為添加了x的k-v 到map中
- 3 打印了1 應(yīng)為key為x的value置為null了