for循環(huán)和foreach循環(huán)
fun main(args: Array<String>) {
val s = "Kotlin"
//普通的for循環(huán)遍歷
for (a in s) {
println("a = $a")
}
//for循環(huán)遍歷加上角標
for ((b, index) in (s.withIndex())) {
println("index = $index , b = $b")
}
//foreach循環(huán)遍歷
s.forEach { println(it) }
//foreach循環(huán)遍歷加上角標
s.forEachIndexed { index, c -> println("index = $index , c = $c") }
}
break和continue
break和continue的用法同java宗雇。在kotlin中,foreach不可被打斷,所以不能用break或continue
fun main(args: Array<String>) {
val str = "abcde"
//遍歷元素:找到c就停止.
for (c in str) {
println(c)
if (c.equals('c'/*字符串的遍歷方法還是變?yōu)樽址M行打印*/))
break
}
//遍歷元素:除了c其它都打印
for (c in str) {
if (c.equals('c')){
continue
}
println(c)
}
}
在特定位置返回
在for循環(huán)中可以嵌套循環(huán)晚伙,方法同java,但是當想要在特定位置返回時,需要在返回的循環(huán)前加上返回名+@洲敢,并且break也需要加返回名+@姜钳。返回名可以任意命名,但不可是關(guān)鍵字
fun main(args: Array<String>) {
val str1 = "abc"
val str2 = "ABC"
//找到str1和str2每一個元素組合
for (c1 in str1) {
for (c2 in str2) {
println("${c1}$c2")
}
}
//找到bB之后就不再打印了
jump@ for (c1 in str1) {
for (c2 in str2) {
println("${c1}$c2")
if (c1 == 'b' && c2 == 'B') {
break@jump
}
}
}
}
區(qū)間
kotlin有三種區(qū)間浴滴,分別是IntRange、CharRange岁钓、LongRange升略。區(qū)間有三種定義的方法
三種區(qū)間的定義方法
fun main(args: Array<String>) {
//定義整形區(qū)間
val range1 = IntRange(1, 100)
val range2 = 1.rangeTo(100)
val range3 = 1..100
//定義字符區(qū)間
val charrange1 = CharRange('a', 'b')
val charrange2 = 'a'.rangeTo('b')
val charrange3 = 'a'..'b'
//定義長整型區(qū)間
val longrange1 = LongRange(1L, 100L)
val longrange2 = 1L.rangeTo(100L)
val longrange3 = 1L..100L
}
區(qū)間的遍歷
區(qū)間遍歷同樣可以使用for和foreach
fun main(args: Array<String>) {
val range = 1..10
//用for循環(huán)遍歷
for (i in range) {
println(i)
}
//加上步長的遍歷
for (i in range.step(2)) {
println(i)
}
//用for循環(huán)遍歷,加上索引
for ((index, i) in range.withIndex()) {
println("index = $index ,i = $i")
}
//用foreach循環(huán)遍歷
range.forEach {
println(it)
}
//用foreach循環(huán)遍歷,加上索引
range.forEachIndexed { index, i -> println("index = $index , i = $i") }
}
反向區(qū)間和區(qū)間的反轉(zhuǎn)
方向區(qū)間可使用down to()實現(xiàn),區(qū)間反轉(zhuǎn)同java中的 reversed()方法
//定義反轉(zhuǎn)區(qū)間
val range = 10 downTo 1
for (i in range) {
println(i)
}
//區(qū)間反轉(zhuǎn)
val range2 = range.reversed()
range2.forEach { println(it) }
數(shù)組
數(shù)組的創(chuàng)建
kotlin中8種基本類型都有對應的數(shù)組類型屡限。建立String類型數(shù)組可通過Array<String>來創(chuàng)建品嚣。
fun main(args: Array<String>) {
//數(shù)組的定義
//如果數(shù)組中元素已知
val arr1 = arrayOf("張三","李四","王五")
val arr2 = arrayOf(1,2,3)
val arr3 = arrayOf("張三",20,"男")//可以設置不同類型元素的數(shù)組
//如果數(shù)組中元素未知
val arr4 = Array<Int>(10){0}//創(chuàng)建一個長度為10的int類型數(shù)組,數(shù)組內(nèi)所有元素初始化值為0
val arr5 = IntArray(10)//創(chuàng)建一個長度為10的int類型數(shù)組
}
數(shù)組的遍歷
數(shù)組遍歷同樣可以用for、for index钧大、foreach翰撑、foreach index來做
fun main(args: Array<String>) {
val arr = arrayOf(1,2,3,4,5,6)
//for
for (s in arr) {
println(s)
}
//for index
for ((i,index) in arr.withIndex()) {
println("i = $i ,index = $index")
}
//foreach
arr.forEach { println(it) }
//foreach index
arr.forEachIndexed { index, i -> println("index = $index , i = $i") }
}
數(shù)組元素訪問以及修改
fun main(args: Array<String>) {
val arr = arrayOf(1, 2, 3, 4, 5, 6)
//數(shù)組元素訪問以及修改
//訪問某一個元素
val e = arr[1]//訪問第二個元素
println(e)
//數(shù)組元素的修改
//第三個元素修改為10
arr[2] = 10
println(arr[2])
arr.set(3, 11)
}
查找數(shù)組元素角標
fun main(args: Array<String>) {
val arr = arrayOf("張三","李四","張五","王五","張四","張三")
//查找第一個"張三"角標
val indexOf = arr.indexOf("張三")
println(indexOf)
//查找最后一個"張三"角標
val lastIndexOf = arr.lastIndexOf("張三")//方法一
println(lastIndexOf)
val array = arr.indexOfLast { it.equals("張三") }
println(array)
//查找第一個姓"張"的人的角標
val arr1 = arr.indexOfFirst { it.startsWith("張") }
println(arr1)
//查找最后一個姓"張"的人的角標
val arr2 = arr.indexOfLast { it.startsWith("張") }
println(arr2)
}
When表達式
when表示式是多分支的條件控制語句,在kotlin中啊央,如果when表達式分支只有一行眶诈,可以省略{}。支持的數(shù)據(jù)格式比java要多劣挫,除了java支持的6中數(shù)據(jù)格式之外可以支持區(qū)間册养,表達式,判斷語句压固。
如果是簡單的when表達式 支持的6中數(shù)據(jù)格式球拦,when表達式最終都會翻譯成switch語句。如果是加強的when表達式帐我,最終會翻譯成if else形式坎炼。
fun todo(age: Int): String {
return when (age) {
in 1..6 -> "沒有上學"
6 -> "開始上小學"
in 7..11 -> "正在上小學"
12 -> "開始上中學"
13, 14 -> "正在上中學"
15 -> "開始上高中"
16, 17 -> "正在上高中"
18 -> "開始上大學"
in 19..22 -> "正在上大學"
else -> "上社會大學"
}
}
when表達式有返回值,如果返回when表達式必須要有else操作拦键。對于when表達式返回值是{}最后一行谣光。
fun todo(age: Int): Any {
return when {
age == 7 -> {
"haha"
println("hello")//如果方法沒有返回值,返回默認是Unit
10
"開始上小學"
}
}
輸出的結(jié)果為 hello,開始上小學
函數(shù)表達式
函數(shù)表達式:如果函數(shù)只有一行處理代碼芬为,就可以省略掉{萄金,以= 連接蟀悦,去掉return以及返回值類型。
函數(shù)表達式只能適用于一行代碼的函數(shù)
fun main(args: Array<String>) {
val a = 10
val b = 20
//求a加b的和
}
//標準格式
fun add(a:Int,b:Int):Int{
return a+b
}
//由于處理代碼只有一行,可以省略掉{},以= 連接,去掉return
fun add2(a:Int,b:Int):Int= a+b
//智能類型推斷
fun add3(a:Int,b:Int) = a+b
函數(shù)變量和函數(shù)引用
在Kotlin中氧敢,對象和函數(shù)的地位相同日戈。對象可以定義對象變量,函數(shù)也可以定函數(shù)變量孙乖。
創(chuàng)建函數(shù)變量
fun main(args: Array<String>) {
val a = 10
val b = 20
var sum = 0
//函數(shù)變量
//求a+b
//定義一個函數(shù)變量
val padd: ((Int, Int) -> Int)? = { m, n -> m + n }//定義函數(shù)
sum = padd?.invoke(a,b)!!//調(diào)用函數(shù)
println(sum)
}
函數(shù)應用
fun main(args: Array<String>) {
val a = 10
val b = 20
var sum = 0
val padd=::add//獲取函數(shù)引用
//調(diào)用函數(shù)
println(padd(a, b))
println(padd.invoke(a, b))
}
fun add(a: Int,b: Int):Int{
return a+b
}
可變參數(shù)
如果接收的參數(shù)個數(shù)不確定浙炼,可以用可變參數(shù)表示。
求多個int類型的和
fun add(vararg a:Int):Int{
var count = 0
for (item in a) {
count+=item
}
return count
}
異常處理
kotlin只有運行時異常唯袄,沒有受檢異常弯屈。即無論方法有沒有拋出異常,編譯器都不會提示處理這個異常(什么鬼設計= =)
fun main(args: Array<String>) {
val a = 10
val b = 0
var c: Int =0
try {
c = a/b
} catch (e: Exception) {
println("出現(xiàn)了異常")
}finally {
}
println(c)
}
遞歸
遞歸的思路同java
計算斐波那契數(shù)列第n項的值
fun main(args: Array<String>) {
println(fbnq(5))
}
fun fbnq(n: Int):Int{
if (n == 1 || n == 2) {
return 1
}
else{
return fbnq(n-1)+ fbnq(n-2)
}
}
遞歸和迭代的比較
kotlin函數(shù)參數(shù)都是不可變的恋拷。一般情況下资厉,遞歸能解決的問題,用普通迭代也能解決梅掠。有一些問題我們用遞歸寫起來會比較簡單酌住,因為遞歸更符合思維邏輯店归。而迭代需要抽象出數(shù)學模型才能解決阎抒。但是,如果遞歸的層級比較深的話就會出現(xiàn)棧內(nèi)存溢出的異常消痛。遞歸寫起來簡單且叁,但是容易內(nèi)存溢出;迭代寫起來麻煩秩伞,但是不容易溢出內(nèi)存逞带。那么,能不能有一種方式既能夠?qū)懫饋砗唵紊葱拢帜軌虿粫?nèi)存溢出呢展氓?于是,kotlin中有了尾遞歸優(yōu)化脸爱。
尾遞歸優(yōu)化
尾遞歸優(yōu)化需要一個前提:這個遞歸必須是尾遞歸遇汞。調(diào)用當前遞歸的方法之后,沒有做任何其它操作就是尾遞歸簿废。
尾遞歸優(yōu)化原理:幫我們把遞歸轉(zhuǎn)換為迭代空入,按照遞歸的方式寫代碼,按照迭代的方式執(zhí)行族檬。
tailrec fun add(n: Int,result:Int = 0):Int{
if (n == 1){
return result+1
}
else{
return add(n-1,result+n)
}
}
tailrec就是尾遞歸優(yōu)化的代碼歪赢,添加在方法前面