kotlin学习第二天

for循环和foreach循环

fun main(args: Array<String>) {
    val s = "Kotlin"
   //普通的for循环遍历
    for (a in s) {
        println("a = $a")
    }
    //for循环遍历加上角标
    for ((b, index) in (s.withIndex())) {
        println("index = $index , b = $b")
    }
    //foreach循环遍历
    s.forEach { println(it) }
    //foreach循环遍历加上角标
    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'/*字符串的遍历方法还是变为字符进行打印*/))
            break
    }
    //遍历元素:除了c其它都打印
    for (c in str) {
        if (c.equals('c')){
            continue
        }
        println(c)
    }
}

在特定位置返回

在for循环中可以嵌套循环,方法同java,但是当想要在特定位置返回时,需要在返回的循环前加上返回名+@,并且break也需要加返回名+@。返回名可以任意命名,但不可是关键字

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
            }
        }
    }
}

区间

kotlin有三种区间,分别是IntRange、CharRange、LongRange。区间有三种定义的方法

三种区间的定义方法

fun main(args: Array<String>) {
    //定义整形区间
    val range1 = IntRange(1, 100)
    val range2 = 1.rangeTo(100)
    val range3 = 1..100
    //定义字符区间
    val charrange1 = CharRange('a', 'b')
    val charrange2 = 'a'.rangeTo('b')
    val charrange3 = 'a'..'b'
    //定义长整型区间
    val longrange1 = LongRange(1L, 100L)
    val longrange2 = 1L.rangeTo(100L)
    val longrange3 = 1L..100L
}

区间的遍历

区间遍历同样可以使用for和foreach

fun main(args: Array<String>) {
    val range = 1..10
    //用for循环遍历
    for (i in range) {
        println(i)
    }
    //加上步长的遍历
    for (i in range.step(2)) {
        println(i)
    }
    //用for循环遍历,加上索引
    for ((index, i) in range.withIndex()) {
        println("index = $index ,i = $i")
    }
    //用foreach循环遍历
    range.forEach {
        println(it)
    }
    //用foreach循环遍历,加上索引
    range.forEachIndexed { index, i -> println("index = $index , i = $i") }
}

反向区间和区间的反转

方向区间可使用down to()实现,区间反转同java中的 reversed()方法

//定义反转区间
val range = 10 downTo 1
for (i in range) {
    println(i)
}
//区间反转
val range2 = range.reversed()
range2.forEach { println(it) }

数组

数组的创建

kotlin中8种基本类型都有对应的数组类型。建立String类型数组可通过Array<String>来创建。

fun main(args: Array<String>) {
    //数组的定义
    //如果数组中元素已知
    val arr1 = arrayOf("张三","李四","王五")
    val arr2 = arrayOf(1,2,3)
    val arr3 = arrayOf("张三",20,"男")//可以设置不同类型元素的数组
    //如果数组中元素未知
    val arr4 = Array<Int>(10){0}//创建一个长度为10的int类型数组,数组内所有元素初始化值为0
    val arr5 = IntArray(10)//创建一个长度为10的int类型数组
}

数组的遍历

数组遍历同样可以用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") }
}

数组元素访问以及修改

fun main(args: Array<String>) {
    val arr = arrayOf(1, 2, 3, 4, 5, 6)
    //数组元素访问以及修改
    //访问某一个元素
    val e = arr[1]//访问第二个元素
    println(e)
    //数组元素的修改
    //第三个元素修改为10
    arr[2] = 10
    println(arr[2])
    arr.set(3, 11)
}

查找数组元素角标

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表达式分支只有一行,可以省略{}。支持的数据格式比java要多,除了java支持的6中数据格式之外可以支持区间,表达式,判断语句。

如果是简单的when表达式 支持的6中数据格式,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

            "开始上小学"

        }
    }

输出的结果为  hello,开始上小学

函数表达式

函数表达式:如果函数只有一行处理代码,就可以省略掉{,以= 连接,去掉return以及返回值类型。

函数表达式只能适用于一行代码的函数

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

函数变量和函数引用

在Kotlin中,对象和函数的地位相同。对象可以定义对象变量,函数也可以定函数变量。

创建函数变量

fun main(args: Array<String>) {
    val a = 10
    val b = 20
    var sum = 0
    //函数变量
    //求a+b
    //定义一个函数变量
    val padd: ((Int, Int) -> Int)? = { m, n -> m + n }//定义函数
    sum = padd?.invoke(a,b)!!//调用函数
    println(sum)
}

函数应用

fun main(args: Array<String>) {
    val a = 10
    val b = 20
    var sum = 0
    val padd=::add//获取函数引用
    //调用函数
    println(padd(a, b))
    println(padd.invoke(a, b))
}
fun add(a: Int,b: Int):Int{
    return a+b
}

可变参数

如果接收的参数个数不确定,可以用可变参数表示。

求多个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("出现了异常")
    }finally {
    }
    println(c)
}

递归

递归的思路同java

计算斐波那契数列第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函数参数都是不可变的。一般情况下,递归能解决的问题,用普通迭代也能解决。有一些问题我们用递归写起来会比较简单,因为递归更符合思维逻辑。而迭代需要抽象出数学模型才能解决。但是,如果递归的层级比较深的话就会出现栈内存溢出的异常。递归写起来简单,但是容易内存溢出;迭代写起来麻烦,但是不容易溢出内存。那么,能不能有一种方式既能够写起来简单,又能够不会内存溢出呢?于是,kotlin中有了尾递归优化。

尾递归优化

尾递归优化需要一个前提:这个递归必须是尾递归。调用当前递归的方法之后,没有做任何其它操作就是尾递归。

尾递归优化原理:帮我们把递归转换为迭代,按照递归的方式写代码,按照迭代的方式执行。

tailrec fun add(n: Int,result:Int = 0):Int{
    if (n == 1){
        return result+1
    }
    else{
        return add(n-1,result+n)
    }
}

tailrec就是尾递归优化的代码,添加在方法前面
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,185评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,652评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,524评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,339评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,387评论 6 391
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,287评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,130评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,985评论 0 275
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,420评论 1 313
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,617评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,779评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,477评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,088评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,716评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,857评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,876评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,700评论 2 354

推荐阅读更多精彩内容

  • kotlin - for循环和foreach循环fun main(args: Array ) { val s...
    s酸菜阅读 517评论 0 0
  • 前言 人生苦多,快来 Kotlin ,快速学习Kotlin! 什么是Kotlin? Kotlin 是种静态类型编程...
    任半生嚣狂阅读 26,208评论 9 118
  • 第2章 基本语法 2.1 概述 基本句法和变量 语句 JavaScript程序的执行单位为行(line),也就是一...
    悟名先生阅读 4,148评论 0 13
  • 【90天小目標】 1、减肥10斤 2、6:00前早起,每周三次3公里,游泳学习 3、和儿子一起培养规律作息 【昨日...
    果果216阅读 194评论 0 0
  • 前段时间我和婆婆之间有了一点点分歧,其实也不是什么大事。婆婆倒是没有什么不开心,但我开始还挺怕她会介意的。 事情的...
    安丽说阅读 712评论 0 1